"Adding" Dictionaries in Python?

Question:

Possible Duplicate:
python dict.add_by_value(dict_2) ?

My input is two dictionaries that have string keys and integer values. I want to add the two dictionaries so that the result has all the keys of the input dictionaries, and the values are the sum of the input dictionaries’ values.

For clarity, if a key appears in only one of the inputs, that key/value will appear in the result, whereas if the key appears in both dictionaries, the sum of values will appear in the result.

For example, say my input is:

a = dict()
a['cat'] = 1
a['fish'] = 10
a['aardvark'] = 1000

b = dict()
b['cat'] = 2
b['dog'] = 200
b['aardvark'] = 2000

I would like the result to be:

{'cat': 3, 'fish': 10, 'dog': 200, 'aardvark': 3000}

Knowing Python there must be a one-liner to get this done (it doesn’t really have to be one line…). Any thoughts?

Asked By: Roee Adler

||

Answers:

result in a:

for elem in b:
    a[elem] = a.get(elem, 0) + b[elem]

result in c:

c = dict(a)
for elem in b:
    c[elem] = a.get(elem, 0) + b[elem]
Answered By: Adrian Panasiuk

How about that:

dict( [ (n, a.get(n, 0)+b.get(n, 0)) for n in set(a)|set(b) ] )

Or without creating an intermediate list (generator is enough):

dict( (n, a.get(n, 0)+b.get(n, 0)) for n in set(a)|set(b) )

Post Scriptum:

As a commentator addressed correctly, there is a way to implement that easier with the new (from Py2.7) collections.Counter class. As much I remember, this version was not available when I wrote the answer:

from collections import Counter
dict(Counter(a)+Counter(b))
Answered By: Juergen

Not in one line, but …

import itertools
import collections
a = dict()
a['cat'] = 1
a['fish'] = 10
a['aardvark'] = 1000
b = dict()
b['cat'] = 2
b['dog'] = 200
b['aardvark'] = 2000
c = collections.defaultdict(int)
for k, v in itertools.chain(a.iteritems(), b.iteritems()):
    c[k] += v

You can easily extend it to a larger number of dictionaries.

Answered By: unbeknown

One liner (as sortof requested): get key lists, add them, discard duplicates, iterate over result with list comprehension, return (key,value) pairs for the sum if the key is in both dicts, or just the individual values if not. Wrap in dict.

>>> dict([(x,a[x]+b[x]) if (x in a and x in b) else (x,a[x]) if (x in a) else (x,b[x]) for x in set(a.keys()+b.keys())])
{'aardvark': 3000, 'fish': 10, 'dog': 200, 'cat': 3}
Answered By: Markus
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.