Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create single Python dict from a list of dicts by summing values with common keys?

Tags:

python

I have a list of dictionaries, e.g:

dictList = [
    {'a':3, 'b':9, 'c':4},
    {'a':9, 'b':24, 'c':99},
    {'a':10, 'b':23, 'c':88}
]

All the dictionaries have the same keys e.g. a, b, c. I wish to create a single dictionary with the same keys where the values are the sums of the values with the same keys from all the dictionaries in the original list.

So for the above example, the output should be:

{'a':22, 'b':56, 'c':191}

What would be the most efficient way of doing this? I currently have:

result = {}
for myDict in dictList:
    for k in myDict:
        result[k] = result.setdefault(k, 0) + myDict[k]
like image 818
msanders Avatar asked Jun 10 '09 10:06

msanders


2 Answers

If all dicts have all keys, you could do this as:

>>> dict((key, sum(d[key] for d in dictList)) for key in dictList[0])
{'a': 22, 'b': 56, 'c': 191}

[Edit] If speed is a big priority, you can also shave off ~20% (though at the cost of some readability) with the following instead:

import operator, itertools
dict((key, sum(itertools.imap(operator.itemgetter(key), dictList))) 
      for key in dictList[0])

The speed depends on the size of the dict. I get the following timings for the original 3 item list, and for various different sizes (created by mutliplying the original list by 10, 100 or 1000 etc):

List Size   Original      dict+generator       imap+itemgetter
      3      0.054          0.090                0.097
     30      0.473          0.255                0.236
    300      4.668          1.884                1.529
   3000     46.668         17.975               14.499

(All times for 10,000 runs)

So it's slightly slower for just 3, but two to three times as fast for larger lists.

like image 124
Brian Avatar answered Nov 20 '22 07:11

Brian


Try this.

from collections import defaultdict
result = defaultdict(int)
for myDict in dictList:
    for k in myDict:
        result[k] += myDict[k]
like image 26
S.Lott Avatar answered Nov 20 '22 08:11

S.Lott