how to merge two nested dictionaries under a same dictionary - python

for example I have a dictionary:
dictA={"nest1":{"01feb":[1,2,3,4,5],"02feb":[1,7,8,9,10]},
"nest2":{"01feb":[1,2,3,4,5],"02feb":[6,4,8,10,10]}}
the list inside has the same length. I need to merge nest1 and nest2 as one dictionary, and the result should be like this:
dictA={"nest":{"01feb":[2,4,6,8,10],"02feb":[7,11,16,19,20]}}

You can use a dict comprehension, map() and zip() like this example (works with Python 2 and Python 3).
dictA = {'nest1': {'01feb': [1, 2, 3, 4, 5], '02feb': [1, 7, 8, 9, 10]},
'nest2': {'01feb': [1, 2, 3, 4, 5], '02feb': [6, 4, 8, 10, 10]}}
a = (v.items() for _, v in map(list, dictA.items()))
# You can also use another map():
# final = {'nest': {k: list(map(sum, zip(v,j))) for (k, v), (_, j) in zip(*a)}}
final = {'nest': {k: [m+n for m, n in zip(v, j)] for (k, v), (_, j) in zip(*a)}}
print(final)
Output:
{'nest': {'02feb': [7, 11, 16, 19, 20], '01feb': [2, 4, 6, 8, 10]}}

Plese find the below code for your query.
dictA={"nest1":{"01feb":[1,2,3,4,5],"02feb":[1,7,8,9,10]},
"nest2":{"01feb":[1,2,3,4,5],"02feb":[6,4,8,10,10]}}
result ={}
final_op = {}
for k,v in dictA.iteritems():
for nk,nv in v.iteritems():
if result.has_key(nk):
i=0
while i < len(result[nk]):
result[nk][i] += nv[i]
i += 1
else:
result[nk] = nv
final_op['nest'] = result
print final_op
Output:
{'nest': {'02feb': [7, 11, 16, 19, 20], '01feb': [2, 4, 6, 8, 10]}}

You have to traverse the dict and update the value in the iteration.
dictA={"nest1":{"01feb":[1,2,3,4,5],"02feb":[1,7,8,9,10]},
"nest2":{"01feb":[1,2,3,4,5],"02feb":[6,4,8,10,10]}}
def merge(dictA):
merge_dict = {}
for key in dictA:
for sub_key in dictA[key]:
if sub_key in merge_dict:
# update the nested value
merge_dict[sub_key] = [sum(x) for x in zip(*[merge_dict[sub_key], dictA[key][sub_key]])]
else:
merge_dict[sub_key] = dictA[key][sub_key]
return merge_dict
merge_dict = merge(dictA)
dictA.clear()
dictA["nest"] = merge_dict
print(dictA)

Here is a function to do what you're asking for:
def merge_nested(dictionary):
result = dict()
for nested in dictionary.values():
for key in nested.keys():
if key in result:
# We've already found it, add our values to it's
for i in range(len(result[key])):
result[key][i] += nested[key][i]
else:
result[key] = nested[key]
return {"nest":result}
With this function you get the following output:
>>> print(merge_nested({"nest1":{"01feb":[1,2,3,4,5],"02feb":[1,7,8,9,10]},"nest2":{"01feb":[1,2,3,4,5],"02feb":[6,4,8,10,10]}}))
{'nest': {'01feb': [2, 4, 6, 8, 10], '02feb': [7, 11, 16, 19, 20]}}
This is a modified version of #Arockia's answer here

A solution with groupby of itertools:
from itertools import chain, groupby
import operator
dictA={"nest1":{"01feb":[1,2,3,4,5],"02feb":[1,7,8,9,10]},
"nest2":{"01feb":[1,2,3,4,5],"02feb":[6,4,8,10,10]}}
A = {
"nest": dict(
(key, list(map(operator.add, *(v for _, v in group))))
for key, group in groupby(
sorted(
chain(*(v.iteritems() for v in dictA.values())) # Python 2
# chain(*(v.items() for v in dictA.values())) # Python 3
),
lambda x: x[0],
)
)
}
print(A)
Result:
{'nest': {'02feb': [7, 11, 16, 19, 20], '01feb': [2, 4, 6, 8, 10]}}

Related

Selecting items in a dictionary

I have the following dictionary
d= {"Month":[1,2,3,4,5,6],"Rain":[30,40,50,20,30,70]}
I want to select certain Rain by ordered by Month, so I get
For example
new_d= {"Month":[2,4,6],"Rain":[40,20,70]}
I'm thinking along this side of a code, I'm still new to coding please help how can I do it without dictionary comprehensions?
for key in d:
if filter_string in key:
# do something
else:
# do nothing, continue
see below
d = {"Month": [1, 2, 3, 4, 5, 6], "Rain": [30, 40, 50, 20, 30, 70]}
interesting_month = [2, 4, 6]
d1 = {'Month': [m for m in interesting_month], 'Rain': [d["Rain"][d['Month'].index(m)] for m in interesting_month]}
print(d1)
output
{'Month': [2, 4, 6], 'Rain': [40, 20, 70]}
first with the for-loop, then as comprehension - as addition to the previous answer:
d = {"Month":[1,2,3,4,5,6],"Rain":[30,40,50,20,30,70]}
#new_d = {"Month":[2,4,6],"Rain":[40,20,70]}
mths_to_choose = [2,4,6]
for keyval in d.items():
new_d[keyval[0]] = []
for i in mths_to_choose: # if filter_string in key: # do something
new_d[keyval[0]].append(keyval[1][i-1])
# else# do nothing, continue
print(new_d)
new_d = {ditms[0]: [ditms[1][i-1] for i in mths_to_choose] for ditms in d.items()}
print(new_d)
output:
{'Month': [2, 4, 6], 'Rain': [40, 20, 70]}
{'Month': [2, 4, 6], 'Rain': [40, 20, 70]}
I hope this might be helpful
d = {"Month": [1, 2, 3, 4, 5, 6], "Rain": [30, 40, 50, 20, 30, 70]}
#Creating a new dictionary
new_d = {}
#First Loop: will get the keys from your original dictionary
for keys in d:
#new_d[keys] = [] - will create an array value for each key found
new_d[keys] = []
#Second Loop: will get the values from the array on each key
for values in d[keys]:
#If the position of "values" is odd then is inserted on new_d[keys] with the append() method
if d[keys].index(values) % 2 != 0:
new_d[keys].append(values)
#Print the outcome
print(new_d)
d = {"Month":[1,2,3,4,5,6], "Rain":[30,40,50,20,30,70]}
#Desired Output: {"Month":[2,4,6],"Rain":[40,20,70]}
selected_month = [2,4,6] #list of months
new_d = {} #create a new dictionary to store selected month and rain
for key in d.items():
new_d[key[0]] = []
for i in selected_month:
new_d[key[0]].append(key[1][i-1])
print(new_d)

Python: create a sub dictionary swapping the keys

I have a Python dictionary with contains lists such as the following:
my_dict = {
'list1':[10, 20, 30, 40, 50],
'list2':[1, 2, 3, 4, 5, 6, 7],
'list3':[10, 100, 200]
}
I want to create another dictionary, whose keys are the same as the first dictionary, but the values are stored under another key of the dictionary, such as the following:
my_desired_dict = {
'list1':{'my_key':[10, 20, 30, 40, 50]},
'list2':{'my_key':[1, 2, 3, 4, 5, 6, 7]},
'list3':{'my_key':[10, 100, 200]}
}
The key name for the inner dictionary will be the same (my_key) for all. How can I achieve this, thanks for the help.
you can achieve that with a simple dict comprehension
new_key = "aKey"
my_dict = {k: {new_key: v} for k, v in my_dict.items()}
my_desired_dict = {k: {'my_key': v} for k, v in my_dict.items()}

How to get the values in the dictionary into the list form and then square them into list

I have a dictionary of values in tuple form, how to get the values in list form.
I want to get values from the tuples and create new lists and create another 3 lists with squares from them.
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
s=list(d.values())
d=[item for t in s for item in t]
print(d)
I used list comprehension i got this output:
[1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Using list comprehension
Expected_output:
[1,3,6,9,12],
[2,4,7,10,13],
[3,5,8,11,14],
squares**2 output above three list :
[1,9,36,81,144],
[4,16,49,100,169],
[9,25,64,121,196]
Provided with a Dictionary
First take a empty list and assign it to a variable “l”
Using list comprehension separate the values and store that in a variable
Iterate the values and append the empty list “l”
Now iterate the “l” using index values i[o], i[1], i[2] and store in various variables respectively
Using map function square the variables and store the values and print them using the list of variables
x = {
1:(1,2,3),
2:(4,5,6),
3:(7,8,9),
4:(10,11,12),
5:(13,14,15)
}
l = []
y = [i for i in x.values()]
for i in y:
l.append(i)
print(l)
m = [i[0] for i in l]
n = [i[1] for i in l]
o = [i[2] for i in l]
m1 = map(lambda i:i**2, m)
n1 = map(lambda i:i**2, n)
o1 = map(lambda i:i**2, o)
print(m)
print(list(m1))
print(n)
print(list(n1))
print(o)
print(list(o1))
you can use zip to collect the index elements of each list together, then use list comprehension to square them
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_vals = list(zip(*dictionary.values()))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
OUTPUT
[(1, 3, 6, 9, 12), (2, 4, 7, 10, 13), (3, 5, 8, 11, 14)]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
Thanks to comments from #roganjosh highlighting that the dict will only be assured to be ordered if the pythong version is 3.6 or higher. If your python version is less than that you would first need to sort the values by order of the keys. Below is an example.
dictionary={2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14),1:(1,2,3)}
ordered_key_val = sorted(dictionary.items(), key=lambda items: items[0])
list_vals = list(zip(*[val for key, val in ordered_key_val]))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
You can use numpy to transpose the entire list once the values of the dictionary are obtained. You can use the below program
import numpy as np
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_out= []
for i in dictionary.keys():
list_out.append(dictionary[i])
tran_list = np.transpose(list_out)
out_list = tran_list*tran_list
Output of this is:
>>> out_list
array([[ 1, 9, 36, 81, 144],
[ 4, 16, 49, 100, 169],
[ 9, 25, 64, 121, 196]])
This is an array output! Anyway if you want it only in the list, ofcourse , you can play with it!
You can do this way:
>>> temp = list(zip(*dictionary.values()))
>>> [list(i) for i in temp]
[[1, 3, 6, 9, 12], [2, 4, 7, 10, 13], [3, 5, 8, 11, 14]]
>>> [[i**2 for i in elem] for elem in temp]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
I have one dictionary here
d={1:(1,2,3),2:(4,5,6),3:(7,8,9),4:(10,11,12),5:(13,14,15)}
first I want to get values in tuple in three lists then I used list comprehension here The below code gives the tuple values in three lists
myList1 = [d [i][0] for i in (d.keys()) ]
print(myList1)
myList2 = [d [i][1] for i in (d.keys()) ]
print(myList2)
myList3 = [d [i][2] for i in (d.keys()) ]
print(myList3)
Here all the tuple values converted into list form
[1, 4, 7, 10, 13]
[2, 5, 8, 11, 14]
[3, 6, 9, 12, 15]
Now I want to squares the elements in three lists here I Used lambda expression the below code squares the elements in the lists
a1= list(map(lambda x: x**2 ,myList1))
print(a1)
a2= list(map(lambda x: x**2 ,myList2))
print(a2)
a3= list(map(lambda x: x**2 ,myList3))
print(a3)
The output is:
[1, 16, 49, 100, 169]
[4, 25, 64, 121, 196]
[9, 36, 81, 144, 225]

Aggregation in array element - python

I have a OP : {'2017-05-06': [3, 7, 8],'2017-05-07': [3, 9, 10],'2017-05-08': [4]}
from the OP I just want another OP :
{'2017-05-06': [15, 11, 10],'2017-05-07': [19, 13, 12],'2017-05-08': [4]}
which means:
Ncleand is 2017-05-06
element total is 18 so '2017-05-06': [3 -18, 7-18, 8-18] = '2017-05-06': [15, 11, 10]
likewise all elements data.
So final output is {'2017-05-06': [15, 11, 10],'2017-05-07': [19, 13, 12],'2017-05-08': [4]}
How to do this?
Note : I am using python 3.6.2 and pandas 0.22.0
code so far :
import pandas as pd
dfs = pd.read_excel('ff2.xlsx', sheet_name=None)
dfs1 = {i:x.groupby(pd.to_datetime(x['date']).dt.strftime('%Y-%m-%d'))['duration'].sum() for i, x in dfs.items()}
d = pd.concat(dfs1).groupby(level=1).apply(list).to_dict()
actuald = pd.concat(dfs1).div(80).astype(int)
sum1 = actuald.groupby(level=1).transform('sum')
m = actuald.groupby(level=1).transform('size') > 1
cleand = sum1.sub(actuald).where(m, actuald).groupby(level=1).apply(list).to_dict()
print (cleand)
From the cleand I want to do this?
In a compact (but somehow inefficient) way:
>>> op = {'2017-05-06': [3, 7, 8],'2017-05-07': [3, 9, 10],'2017-05-08': [4]}
>>> { x:[sum(y)-i for i in y] if len(y)>1 else y for x,y in op.items() }
#output:
{'2017-05-06': [15, 11, 10], '2017-05-07': [19, 13, 12], '2017-05-08': [4]}
def get_list_manipulation(list_):
subtraction = list_
if len(list_) != 1:
total = sum(list_)
subtraction = [total-val for val in list_]
return subtraction
for key, values in data.items():
data[key] = get_list_manipulation(values)
>>>{'2017-05-06': [15, 11, 10], '2017-05-07': [19, 13, 12], '2017-05-08': [4]}

Sum different lists from dictionaries PYTHON

I have a data structure. A list of 4 dictionaries each with 4 keys and 3 values in a list.
dict_list = [0] {key1: [1, 2, 3]
key2: [4, 5, 6]
key3: [7, 8, 9]
key4: [10, 11, 12]
[1] {key1: [13.......]
key2: [16... etc.
I want to sum each sub column [1, 4, 7, 10]....[2,5,8,11] etc. into the form
new_dict_list = [0] {new_key: [(1+4+7+10), (2,5,8,11), (3,6,9,12)]
[1] {new_key2: [(13+16....) etc.
So I'm basically cascading each column within each dictionary.
I have a VERY explicit and long way to do it so far (checking the math is correct), is there any way to use list comprehensions for something this long-winded or is it not worth the effort in the end?
Use zip to group [1, 4, 7, 10]....[2,5,8,11]:
>>> d = dict_list[0]
>>> zip(*d.values())
[(7, 4, 1, 10), (8, 5, 2, 11), (9, 6, 3, 12)]
Use map to generate the new list:
>>> map(sum, zip(*d.values()))
[22, 26, 30]
If you are using python3.x, you need list(map...) to get the list.
You can use zip and sum function :
dict_lis=[{next(d.iterkeys()):map(sum,zip(*d.values()))} for d in dict_lis]
dict.iterkeys() will returns an iterator of dictionary keys which you can get the first key using next function.but note that it wouldn't return the first key in the order that you have defined your dictionaries.since dictionary items are not ordered you can use collections.OrderedDict to get a ordered dictionary.
Note that you shouldn't have same key in your dictionaries!since you can not use same key in the last combined dictionary!
example :
dict_lis=[{'key1': [1, 2, 3],'key2': [4, 5, 6],'key3': [7, 8, 9],'key4': [10, 11, 12]},{'key5': [13,14,15],'key6': [16,17,18]}]
print [{next(d.iterkeys()):map(sum,zip(*d.values()))} for d in dict_lis]
[{'key3': [22, 26, 30]}, {'key6': [29, 31, 33]}]
Original version using list comprehensions:
# set up the initial data
dict_list = []
dict_list.append({'key1': range(1,4),
'key2': range(4,7),
'key3': range(7,10),
'key4': range(10,13)})
dict_list.append({'key1': range(13,16),
'key2': range(16,19),
'key3': range(19,22),
'key4': range(22,25)})
# generate the new list
new_dict_list = []
for d in dict_list:
new_dict_list.append({'new_key': [sum(v[0] for v in d.values()),
sum(v[1] for v in d.values()),
sum(v[2] for v in d.values())] })
print new_dict_list
The output looks like this:
[{'new_key': [22, 26, 30]}, {'new_key': [70, 74, 78]}]

Categories