Reputation: 53
I have 2 dictionaries that share about 80% the same keys and the values are 2 element lists. I need to make a new dictionary out of the three that will contain all the keys, including the ones unique to each dictionary and I need the values of the same keys to be summed up.
dict1 = {'Mike': [10,20], 'John': [12,34], 'Steve': [60,10]}
dict2 = {'Mike': [15,10], 'John': [18,36]}
The new dictionary should look like this :
dict3 = {'Mike': [25,30], 'John': [30,70], 'Steve': [60,10]}
Any idea how I should tackle this ?
Upvotes: 1
Views: 2243
Reputation: 1166
Try this:
dict1 = {'Mike': [10,20], 'John': [12,34], 'Steve': [60,10]}
dict2 = {'Mike': [15,10], 'John': [18,36]}
new_dict = {}
for x, y in dict1.items():
if x in dict2.keys():
new_dict[x] = [a + b for a, b in zip(dict2[x], dict1[x])]
else:
new_dict[x] = dict1[x]
print(new_dict)
#Output : {'Mike': [25, 30], 'John': [30, 70], 'Steve': [60, 10]}
Upvotes: 1
Reputation: 8224
Here's my attempt at a somewhat functional solution for any number of dicts and any number of values to zip-sum.
Define how you want to merge entries. In this case by summing the individual components, materializing the result:
merge = lambda vs: list(map(sum, zip(*vs)))
Then define how to merge two dicts:
def merge_dicts(ds):
keys = set.union(*map(set, ds))
return {k: merge(map(lambda d: d.get(k, repeat(0)), ds))
for k in keys}
Here I just go over the union of all keys, merging every dict's entry, with repeat(0)
as default so merge()
will just sum up zeroes for missing values.
After that you can merge your dicts like this:
merged = merge_dicts([dict1, dict2])
Upvotes: 3
Reputation: 6376
my solution use numpy :
import numpy as np
sum_dict = {}
for key in set(dict1.keys() + dict2.keys()):
sum_dict[key] = np.add(dict1.get(key, np.zeros(2)), dict2.get(key, np.zeros(2)))
And convert back to dict of list if you want
dict([(k,list(v)) for (k,v) in sum_dict.items()])
Out[99]:
{'John': [30, 70], 'Mike': [25, 30], 'Steve': [60.0, 10.0]}
Upvotes: 1
Reputation: 141
There are lots of ways to do this, but here is a way that minimizes lookups, which may be helpful if the actual dicts are large:
keys_1 = set(dict1.keys())
keys_2 = set(dict2.keys())
all_keys = keys_1 | keys_2
for key in all_keys:
a,b = 0,0
if key in keys_1:
a += dict1[key][0]
b += dict1[key][1]
if key in keys_2:
a += dict2[key][0]
b += dict2[key][1]
dict3[key] = [a,b]
Upvotes: 3
Reputation: 1056
Take keys from both dicts, iterate through and populate dict3 depending on where that key in both_key
belongs to
both_keys = set(list(dict1.keys()) + list(dict2.keys()))
dict3 = {}
for k in both_keys:
if k in dict1 and k in dict2:
dict3[k] = [sum(x) for x in zip(dict1[k], dict2[k])]
elif k in dict1:
dict3[k] = dict1[k]
else:
dict3[k] = dict2[k]
Upvotes: 2