如何通过使用公共密钥对值进行求和,从一系列dicts创建单个Python dict?

时间:2009-06-10 10:01:47

标签: python

我有一个词典列表,例如:

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

所有词典都有相同的键,例如 a b c 。我希望创建一个具有相同键的单个字典,其中值是原始列表中所有字典中具有相同键的值的总和。

因此,对于上面的示例,输出应为:

{'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 :(得分: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个稍慢,但对于较大的列表来说快两到三倍。

答案 1 :(得分:7)

试试这个。

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

答案 2 :(得分:0)

我不确定它与速度明智的其他答案有什么关系,但总有

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

Counterdict的子类,在大多数地方可以用它来代替dict。如有必要,您可以将其转换回dict

result = dict(result)