"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?
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]
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))
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.
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}
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?
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]
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))
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.
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}