Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum corresponding elements of multiple python dictionaries

I have an arbitrary number of equal-length python dictionaries with matching sets of keys, like this:

{'a':1, 'b':4, 'c':8, 'd':9}

{'a':2, 'b':3, 'c':2, 'd':7}

{'a':0, 'b':1, 'c':3, 'd':4}
...

How can I obtain a single dictionary with the same set of keys but with values as the sums of corresponding elements in the dictionary set? In other words, I'd want:

{'a':3, 'b':8, 'c':13, 'd':20}

Maybe there's an ugly, complicated loop structure, but is there a nicer way to do this with some kind of list/dict comprehension cleverness? Come to think of it, I'm really not sure how to make an ugly loop version, anyway..

like image 334
norman Avatar asked Oct 19 '13 02:10

norman


1 Answers

collections.Counter() to the rescue ;-)

from collections import Counter
dicts = [{'a':1, 'b':4, 'c':8, 'd':9},
         {'a':2, 'b':3, 'c':2, 'd':7},
         {'a':0, 'b':1, 'c':3, 'd':4}]
c = Counter()
for d in dicts:
    c.update(d)

Then:

>>> print c
Counter({'d': 20, 'c': 13, 'b': 8, 'a': 3})

Or you can change it back to a dict:

>>> print dict(c)
{'a': 3, 'c': 13, 'b': 8, 'd': 20}

It doesn't matter to Counter() whether all the input dicts have same keys. If you know for sure that they do, you could try ridiculous ;-) one-liners like this:

d = {k: v for k in dicts[0] for v in [sum(d[k] for d in dicts)]}

Counter() is clearer, faster, and more flexible. To be fair, though, this slightly less ridiculous one-liner is less ridiculous:

d = {k: sum(d[k] for d in dicts) for k in dicts[0]}
like image 150
Tim Peters Avatar answered Oct 21 '22 15:10

Tim Peters