add dictionaries to empty list dict.value() - python

I have four dictionaries I would like to add as items in empty list that is a dictionary value. and I have no idea how to do this. Could someone please help me figure out how to turn this:
data = {'Cars': []}
dict1 = {'subaru': 1, 'honda': 5, 'volkswagen': 8}
dict2 = {'subaru': 7, 'honda': 3, 'volkswagen': 9}
dict3 = {'subaru': 9, 'honda': 2, 'volkswagen': 1}
dict4 = {'subaru': 2, 'honda': 8, 'volkswagen': 2}
print (data)
into this:
{'Cars': [{'subaru': 1, 'honda': 5, 'volkswagen': 8},
{'subaru': 7, 'honda': 3, 'volkswagen': 9},
{'subaru': 9, 'honda': 2, 'volkswagen': 1},
{'subaru': 2, 'honda': 8, 'volkswagen': 2}]}

data = {'Cars': []}
dict1 = {'subaru': 1, 'honda': 5, 'volkswagen': 8}
dict2 = {'subaru': 7, 'honda': 3, 'volkswagen': 9}
dict3 = {'subaru': 9, 'honda': 2, 'volkswagen': 1}
dict4 = {'subaru': 2, 'honda': 8, 'volkswagen': 2}
for item in [dict1, dict2, dict3, dict4]:
data['Cars'].append(item)
import pprint
pp = pprint.PrettyPrinter()
pp.pprint(data)
gives:
{'Cars': [{'subaru': 1, 'honda': 5, 'volkswagen': 8},
{'subaru': 7, 'honda': 3, 'volkswagen': 9},
{'subaru': 9, 'honda': 2, 'volkswagen': 1},
{'subaru': 2, 'honda': 8, 'volkswagen': 2}]}
Citation: """data['Cars'] is your initially-empty list. You add elements to a list by calling .append() on it. Thus, data['Cars'].append(dict1), and so on.""" – jasonharper
and this can be done in one step in a loop constructed as above.
To get the pretty print you import the pprint module, create a pp object using pp = pprint.PrettyPrinter() and use it's pp.pprint() function to print the list nested in the dictionary in a pretty way :) .
By the way: you can create the data dictionary with a list already containing the elements in one step using:
data = {'Cars': [
{'subaru': 1, 'honda': 5, 'volkswagen': 8},
{'subaru': 7, 'honda': 3, 'volkswagen': 9},
{'subaru': 9, 'honda': 2, 'volkswagen': 1},
{'subaru': 2, 'honda': 8, 'volkswagen': 2}]}

You need to access the Cars key in the data dictionary, then append to that.
data = {'Cars': []}
dict1 = {'subaru': 1, 'honda': 5, 'volkswagen': 8}
dict2 = {'subaru': 7, 'honda': 3, 'volkswagen': 9}
dict3 = {'subaru': 9, 'honda': 2, 'volkswagen': 1}
dict4 = {'subaru': 2, 'honda': 8, 'volkswagen': 2}
data['Cars'].append(dict1)
data['Cars'].append(dict2)
data['Cars'].append(dict3)
data['Cars'].append(dict4)
You could simplify this to just
data['Cars'].append({'subaru': 1, 'honda': 5, 'volkswagen': 8})
data['Cars'].append({'subaru': 7, 'honda': 3, 'volkswagen': 9})
data['Cars'].append({'subaru': 9, 'honda': 2, 'volkswagen': 1})
data['Cars'].append({'subaru': 2, 'honda': 8, 'volkswagen': 2})

Just append all the dicts to your data["Cars"] which is a list.
for i in [dict1, dict2, dict3, dict4]:
data["Cars"].append(i)
print data

Related

Variable Locality

I'm trying to implement Dijkstra alogorthim. While doing so, I've coded graph part.
I'm observing this strange output. Not sure which feature causing this. I'm getting same output for two print though one is local variable and another is in class.
class Graph(object):
def __init__(self, nodes, init_graph):
self.nodes = nodes
self.graph = self.construct_graph(nodes, init_graph)
def construct_graph(self, nodes, init_graph):
'''
This method makes sure that the graph is symmetrical.
In other words, if there's a path from node A to B with a value V, there needs to be a path from node B to node A with a value V.
:param self:
:param nodes:
:param init_graph:
:return:
'''
graph = {}
for node in nodes:
graph[node] = {}
graph.update(init_graph)
for node, edges in graph.items():
for adjacent_node, value in edges.items():
if graph[adjacent_node].get(node, False) == False:
graph[adjacent_node][node] = value
print(graph)
return graph
if __name__=="__main__":
nodes = ["Reykjavik", "Oslo", "Moscow", "London", "Rome", "Berlin", "Belgrade", "Athens"]
init_graph = {}
for node in nodes:
init_graph[node] = {}
init_graph["Reykjavik"]["Oslo"] = 5
init_graph["Reykjavik"]["London"] = 4
init_graph["Oslo"]["Berlin"] = 1
init_graph["Oslo"]["Moscow"] = 3
init_graph["Moscow"]["Belgrade"] = 5
init_graph["Moscow"]["Athens"] = 4
init_graph["Athens"]["Belgrade"] = 1
init_graph["Rome"]["Berlin"] = 2
init_graph["Rome"]["Athens"] = 2
graph = Graph(nodes, init_graph)
print(init_graph)
Output :
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}
Expected Output :
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3}, 'Moscow': {'Belgrade': 5, 'Athens': 4}, 'London': {}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {}, 'Belgrade': {}, 'Athens': {'Belgrade': 1}}
graph.update(init_graph) creates references to the nested dictionaries in init_graph rather than creating a separate copy. This allows the data in init_graph to be overwritten and is causing the strange outputs.
This fixed the issue for me:
from copy import deepcopy
graph = Graph(nodes, deepcopy(init_graph))
Here's some info on dictionary copying that was helpful for me: Copy a Python Dictionary: A Complete Guide

How to compare two nested dictionaries with the same keys and update values with a condition in python?

d1 = {'Berlin': {'Boston' : 9, 'LA' : 7, 'Chicago' : 1},
'Vienna': {'Boston' : 5, 'LA' : 2, 'Chicago' : 8},
'London': {'Boston' : 8, 'LA' : 6, 'Chicago' : 5}}
d2 = {'Berlin': {'Boston' : 8, 'LA' : 9, 'Chicago' : 4},
'Vienna': {'Boston' : 3, 'LA' : 1, 'Chicago' : 5},
'London': {'Boston' : 5, 'LA' : 8, 'Chicago' : 8}}
I would like to update the values in d1 if the values in d2 smaller than in d1 to get a new dictionary d:
d = {'Berlin': {'Boston' : 8, 'LA' : 7, 'Chicago' : 1},
'Vienna': {'Boston' : 3, 'LA' : 1, 'Chicago' : 5},
'London': {'Boston' : 5, 'LA' : 6, 'Chicago' : 5}}
This works as per your requirement (take min of dict items by iterating them together via zip and re-combine as a dict again, put it as value with same k as the key again):
d1 = {'Berlin': {'Boston' : 9, 'LA' : 7, 'Chicago' : 1},
'Vienna': {'Boston' : 5, 'LA' : 2, 'Chicago' : 8},
'London': {'Boston' : 8, 'LA' : 6, 'Chicago' : 5}}
d2 = {'Berlin': {'Boston' : 8, 'LA' : 9, 'Chicago' : 4},
'Vienna': {'Boston' : 3, 'LA' : 1, 'Chicago' : 5},
'London': {'Boston' : 5, 'LA' : 8, 'Chicago' : 8}}
>>> {k: dict([min(i, j) for i, j in zip(d1[k].items(), d2[k].items())]) for k in d1.keys()}
{'Berlin': {'Boston': 8, 'LA': 7, 'Chicago': 1},
'Vienna': {'Boston': 3, 'LA': 1, 'Chicago': 5},
'London': {'Boston': 5, 'LA': 6, 'Chicago': 5}}
This data seems like it would be better as a dataframe (basically a table) instead of a nested dict.
Once you create the input dataframes, you just need to combine them using a function that selects the minimal value for each cell. Here's a way to do that straight from the documentation:
import numpy as np
import pandas as pd
df1 = pd.DataFrame(d1)
df2 = pd.DataFrame(d2)
df_new = df1.combine(df2, np.minimum)
print(df_new)
Output:
Berlin Vienna London
Boston 8 3 5
LA 7 1 6
Chicago 1 5 5
If you need to get it back to a dict, you can use DataFrame.to_dict():
d = df_new.to_dict()
Which becomes:
{'Berlin': {'Boston': 8, 'LA': 7, 'Chicago': 1},
'Vienna': {'Boston': 3, 'LA': 1, 'Chicago': 5},
'London': {'Boston': 5, 'LA': 6, 'Chicago': 5}}
P.S. I'm not an expert at Pandas

Using reduce on a list of dictionaries of dictionaries

Here is the given list.
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
I need to use the map and reduce function so that I can have a final result of
{'dogs': 10, 'cats': 7, 'fish': 4}
I have written a function using map
def addDict(d):
d2 = {}
for outKey, inKey in d.items():
for inVal in inKey:
if inVal in d2:
d2[inVal] += inKey[inVal]
else:
d2[inVal] = inKey[inVal]
return d2
def addDictN(L):
d2 = list(map(addDict, L))
print(d2)
That returns
[{'dogs': 5, 'cats': 5, 'fish': 1}, {'dogs': 5, 'cats': 2, 'fish': 3}]
It combines the f1 and f2 of the first and second dictionaries, but I am unsure of how to use reduce on the dictionaries to get the final result.
You can use collections.Counter to sum your list of counter dictionaries.
Moreover, your dictionary flattening logic can be optimised via itertools.chain.
from itertools import chain
from collections import Counter
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
lst = list(chain.from_iterable([i.values() for i in Pets]))
lst_sum = sum(map(Counter, lst), Counter())
# Counter({'cats': 7, 'dogs': 10, 'fish': 4})
This works for an arbitrary length list of dictionaries, with no key matching requirements across dictionaries.
The second parameter of sum is a start value. It is set to an empty Counter object to avoid TypeError.
Without using map and reduce, I would be inclined to do something like this:
from collections import defaultdict
result = defaultdict()
for fdict in pets:
for f in fdict.keys():
for pet, count in fdict[f].items():
result[pet] += count
Using reduce (which really is not the right function for the job, and is not in Python 3) on your current progress would be something like this:
from collections import Counter
pets = [{'dogs': 5, 'cats': 5, 'fish': 1}, {'dogs': 5, 'cats': 2, 'fish': 3}]
result = reduce(lambda x, y: x + Counter(y), pets, Counter())
You can use purely map and reduce like so:
Pets = [{'f1': {'dogs': 2, 'cats': 3, 'fish': 1},
'f2': {'dogs': 3, 'cats': 2}},
{'f1': {'dogs': 5, 'cats': 2, 'fish': 3}}]
new_pets = reduce(lambda x, y:[b.items() for _, b in x.items()]+[b.items() for _, b in y.items()], Pets)
final_pets = dict(reduce(lambda x, y:map(lambda c:(c, dict(x).get(c, 0)+dict(y).get(c, 0)), ['dogs', 'cats', 'fish']), new_pets))
Output:
{'fish': 4, 'cats': 7, 'dogs': 10}

Sort list of dictionaries based on nested keys

[{'AvailableOffers': (d7b000a:Order {Amount:1000,Name:"000091",OfferedC:"JD",SeekingC:"Taobao",UserName:"xalima",ValidTill:"2019-11-30"}), 'Participants': 2, 'OrderID': ['000089', '000091', '000089']}
{'AvailableOffers': (d7b000a:Order {Amount:1000,Name:"000091",OfferedC:"JD",SeekingC:"Taobao",UserName:"xalima",ValidTill:"2019-11-30"}), 'Participants': 2, 'OrderID': ['000089', '000091', '000089']}
{'AvailableOffers': (b222004:Order {Amount:1000,Name:"000093",OfferedC:"JD",SeekingC:"China Airline",UserName:"yunis",ValidTill:"2017-11-11"}), 'Participants': 3, 'OrderID': ['000089', '000093', '000090', '000089']}
{'AvailableOffers': (d7b000a:Order {Amount:1000,Name:"000091",OfferedC:"JD",SeekingC:"Taobao",UserName:"xalima",ValidTill:"2019-11-30"}), 'Participants': 5, 'OrderID': ['000089', '000091', '000096', '000095', '000090', '000089']}
{'AvailableOffers': (d7b000a:Order {Amount:1000,Name:"000091",OfferedC:"JD",SeekingC:"Taobao",UserName:"xalima",ValidTill:"2019-11-30"}), 'Participants': 6, 'OrderID': ['000089', '000091', '000096', '000097', '000093', '000090', '000089']}]
That is the list dictionary I want to sort, what i can do now is to sort
ListData_by_Participants = sorted(ListData, key=itemgetter("Participants"))
What i want to get help is
ListData_by_Validity = sorted(ListData,
key=itemgetter("AvailableOffers")("ValidTill"))
is there a way to manage this ?
In order to sort list of dictionary with nested keys, you may use lambda expression as:
my_dict_list = [{'parent_key': {'my_key_1': 10, 'my_key_2': 2}},
{'parent_key': {'my_key_1': 5, 'my_key_2': 4}},
{'parent_key': {'my_key_1': 10, 'my_key_2': 6}},
{'parent_key': {'my_key_1': 5, 'my_key_2': 2}},
{'parent_key': {'my_key_1': 10, 'my_key_2': 3}},
]
sorted(my_dict_list, key=lambda x: (
x['parent_key']['my_key_1'], x['parent_key']['my_key_2']))
# value of first 'key' to sort-^ ^
# in case of same value for first 'key'-^
# sort based on second key -------------^
which returns the sorted list as:
[{'parent_key': {'my_key_2': 2, 'my_key_1': 5}},
{'parent_key': {'my_key_2': 4, 'my_key_1': 5}},
{'parent_key': {'my_key_2': 2, 'my_key_1': 10}},
{'parent_key': {'my_key_2': 3, 'my_key_1': 10}},
{'parent_key': {'my_key_2': 6, 'my_key_1': 10}}]

how to combine list of list in python into a list of dicts?

I have a list here
arg_list = ['arg1','arg2','arg3','arg4']
value_list = [[1,2,3,4],[5,6,7,8],[3,5,2,4]]
I'd like to convert this into a list of dict objects
[{'arg1':1,'arg2':2,'arg3':3,'arg4':4},{'arg1':5,'arg2':6,'arg3':7,'arg4':8}....etc]
How can i get this done in the most pythonic fashion?
In [3]: [dict(zip(arg_list, e)) for e in value_list]
Out[3]:
[{'arg1': 1, 'arg2': 2, 'arg3': 3, 'arg4': 4},
{'arg1': 5, 'arg2': 6, 'arg3': 7, 'arg4': 8},
{'arg1': 3, 'arg2': 5, 'arg3': 2, 'arg4': 4}]

Categories