简体   繁体   中英

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

I have a list of dictionaries, eg:

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 eg 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]

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.

Try this.

from collections import defaultdict
result = defaultdict(int)
for myDict in dictList:
    for k in myDict:
        result[k] += myDict[k]

I'm not sure how it relates to the other answers speed wise, but there is always

from collections import Counter
result = sum(map(Counter,dictList),Counter())

Counter is a subclass of dict and it can be used in place of dict in most places. If necessary, you could just convert it back into a dict

result = dict(result)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM