如何总结字典元素

在Python中,我有一个dicts列表:

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}] 

我想要一个包含所有字典总和的最后一个字典。 即结果将是: {'a':5, 'b':7}

注意:列表中的每个字典都包含相同数量的键值对。

有点难看,但是是一个单线:

 dictf = reduce(lambda x, y: dict((k, v + y[k]) for k, v in x.iteritems()), dict1) 

你可以使用collections.Counter

 counter = collections.Counter() for d in dict1: counter.update(d) 

或者,如果你喜欢的话:

 functools.reduce(operator.add, map(collections.Counter, dict1)) 

在添加多个字符时,利用sum()应该会获得更好的性能

 >>> dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}] >>> from operator import itemgetter >>> {k:sum(map(itemgetter(k), dict1)) for k in dict1[0]} # Python2.7+ {'a': 5, 'b': 7} >>> dict((k,sum(map(itemgetter(k), dict1))) for k in dict1[0]) # Python2.6 {'a': 5, 'b': 7} 

join斯蒂芬的build议

 >>> {k: sum(d[k] for d in dict1) for k in dict1[0]} # Python2.7+ {'a': 5, 'b': 7} >>> dict((k, sum(d[k] for d in dict1)) for k in dict1[0]) # Python2.6 {'a': 5, 'b': 7} 

我认为Stephan的Python2.7代码版本读起来非常好

这可能有助于:

 def sum_dict(d1, d2): for key, value in d1.items(): d1[key] = value + d2.get(key, 0) return d1 >>> dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}] >>> reduce(sum_dict, dict1) {'a': 5, 'b': 7} 

以下代码显示了一种方法:

 dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}] final = {} for k in dict1[0].keys(): # Init all elements to zero. final[k] = 0 for d in dict1: for k in d.keys(): final[k] = final[k] + d[k] # Update the element. print final 

这输出:

 {'a': 5, 'b': 7} 

如你所愿。

或者,受到克里斯的启发,更好但仍然可读:

 dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}] final = {} for d in dict1: for k in d.keys(): final[k] = final.get(k,0) + d[k] print final 

我松了原始的,可读的Python的日子:-)

我对build议的计数器的性能感兴趣,对大列表的减法和求和方法感兴趣。 也许别人也对此感兴趣。 你可以看看这里: https : //gist.github.com/torstenrudolf/277e98df296f23ff921c

我testing了这个词典列表的三种方法:

 dictList = [{'a': x, 'b': 2*x, 'c': x**2} for x in xrange(10000)] 

总和方法performance最好,其次是减less,Counter是最慢的。 下面显示的时间以秒为单位。

 In [34]: test(dictList) Out[34]: {'counter': 0.01955194902420044, 'reduce': 0.006518083095550537, 'sum': 0.0018319153785705566} 

但这取决于词典中的元素数量。 总和方法将比减less速度减慢。

 l = [{y: x*y for y in xrange(100)} for x in xrange(10000)] In [37]: test(l, num=100) Out[37]: {'counter': 0.2401433277130127, 'reduce': 0.11110662937164306, 'sum': 0.2256883692741394} 

这是一个合理的美丽的一个。

 final = {} for k in dict1[0].Keys(): final[k] = sum(x[k] for x in dict1) return final 

在Python 2.7中,你可以用一个collections.Counter对象replace字典。 这支持计数器的加减。

另一个解决scheme

 dict( functools.reduce( lambda x, y: x.update(y) or x, # update, returns None, and we need to chain. dict1, collections.Counter()) ) 

这只创build一个计数器,将其用作累加器,最后转换回字典。