没有比这更简单的了,我认为:
a=[("13.5",100)]
b=[("14.5",100), ("15.5", 100)]
c=[("15.5",100), ("16.5", 100)]
input=[a,b,c]
from collections import Counter
print sum(
(Counter(dict(x)) for x in input),
Counter())
请注意,Counter
(也称为多重集)是数据最自然的数据结构(一种元素可以多次属于的集合类型,或等效地 - 具有语义 Element -> OccurrenceCount 的映射。您可以在第一位,而不是元组列表。
也可以:
from collections import Counter
from operator import add
print reduce(add, (Counter(dict(x)) for x in input))
使用reduce(add, seq)
而不是sum(seq, initialValue)
通常更灵活,并允许您跳过传递多余的初始值。
请注意,您还可以使用operator.and_
查找多重集的交集而不是总和。
上面的变体非常慢,因为每一步都会创建一个新的 Counter 。让我们解决这个问题。
我们知道Counter+Counter
返回一个新Counter
的合并数据。这没关系,但我们想避免额外的创建。让我们Counter.update
改用:
update(self, iterable=None, **kwds) 未绑定的 collections.Counter 方法
像 dict.update() 但添加计数而不是替换它们。Source 可以是可迭代的、字典或另一个 Counter 实例。
这就是我们想要的。让我们用兼容的函数包装它,reduce
看看会发生什么。
def updateInPlace(a,b):
a.update(b)
return a
print reduce(updateInPlace, (Counter(dict(x)) for x in input))
这仅比 OP 的解决方案慢一点。
基准测试:http : //ideone.com/7IzSx (更新了另一个解决方案,感谢astynax)
(另外:如果你非常想要一个单线,你可以用相同的方式替换updateInPlace
它lambda x,y: x.update(y) or x
,甚至被证明更快,但在可读性方面失败。不要:-))