问题
Given three dicts d1, d2 and d3:
d1
{'a':1,'b':2,'c':3, 'd':0)
d2
{'b':76}
d3
{'a': 45, 'c':0}
There are some key names that are common to more than one dict (and in reality, they will represent the same real-life object). Others such as 'd' in d1 only exist in d2. I want to group all dicts together, first summing the values of the common keys first, ending up with:
{'a':46, 'b':78, 'c':3, 'd': 0}
If every dict were the same size and contained the same keys, I could do something like:
summedAndCombined = {}
for k,v in d1.items():
summedAndCombined[k] = d1[k]+d2[k]+d3[k]
But this will break down as soon as it reaches a key that is in d1 but not in the others. How do we achieve this?
UPDATE
Not a duplicate. collections.Counter almost works, but the key d is missing from the resulting Counter if the value of key d is zero, which it is above.
In [128]: d1 = {'a':1,'b':2,'c':3, 'd':0}
In [129]: d2 = {'b':76}
In [130]: d3 = {'a': 45, 'c':0}
In [131]: from collections import Counter
In [132]: Counter(d1) + Counter(d2) + Counter(d3)
Out[132]: Counter({'b': 78, 'a': 46, 'c': 3})
回答1:
You could use update
instead of +
with Counter
if you want the 0 keys to persist:
>>> c = Counter()
>>> for d in d1, d2, d3:
... c.update(d)
...
>>> c
Counter({'b': 78, 'a': 46, 'c': 3, 'd': 0})
(This is probably a dup, but I can't find it right now.)
回答2:
UNTESTED:
def merge_dicts(*dicts):
res = {}
for key in set(sum(map(list, dicts), [])):
res[key] = 0
for dct in dicts:
res[key] += dct.get(key, 0)
return res
Example usage:
merge_dicts(d1, d2, d3)
回答3:
collections.defaultdict
to the rescue
import collections
d = collections.defaultdict(int)
for thing in [d1, d2, d3]:
for k, v in thing.items():
d[k] += v
来源:https://stackoverflow.com/questions/31226379/how-to-combine-multiple-dicts-summing-the-values-of-common-keys-and-retaining