如何通过对共同键的值求和,从字典列表创建单一Python字典?

7 投票
3 回答
5993 浏览
提问于 2025-04-15 12:09

我有一个字典的列表,比如说:

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

这些字典都有相同的键,比如说 abc。我想创建一个新的字典,键还是这些相同的键,但值是原来所有字典中相同键的值的总和。

所以根据上面的例子,输出应该是:

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

那么,有什么高效的方法来实现这个呢?我现在有:

result = {}
for myDict in dictList:
    for k in myDict:
        result[k] = result.setdefault(k, 0) + myDict[k]

3 个回答

0

我不太确定这个和其他答案在速度上有什么关系,但总是有

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

Counterdict 的一个子类,通常可以在大多数地方替代 dict 使用。如果需要的话,你可以把它再转换回 dict

result = dict(result)
7

试试这个。

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

如果所有的字典都有相同的键,你可以这样做:

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

[编辑] 如果速度是一个很重要的考虑因素,你可以用下面的方法提高大约20%的速度(不过这样可能会让代码看起来不那么容易理解):

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

速度的快慢跟字典的大小有关。我对原来的3个项目的列表和通过把原列表乘以10、100或1000等方式创建的不同大小的列表进行了测试,得到了以下的时间:

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

(所有时间都是针对运行10,000次的结果)

所以对于只有3个项目的情况,速度稍微慢一点,但对于更大的列表来说,速度快了两到三倍。

撰写回答