Khalil Mansour
Khalil Mansour

Reputation: 53

Python: Adding values from multiple dictionaries and merging unique keys

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

Answers (5)

Sagar Dawda
Sagar Dawda

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

Felk
Felk

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

Espoir Murhabazi
Espoir Murhabazi

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)))
  1. concatenate all the 2 keys
  2. loop and using numpy add to sum the values, and the default value is a numpy array of zeros

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

Samuel Henderson
Samuel Henderson

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

jimmu
jimmu

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

Related Questions