これ以上簡単なことはないと思います:
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
new を返すことがわかっています。Counter
これは問題ありませんが、余分な作成は避けたいと思います。Counter.update
代わりに使用しましょう:
update(self, iterable=None, **kwds) unbound collections.Counter メソッド
dict.update() と似ていますが、カウントを置き換える代わりに追加します。ソースは、イテラブル、辞書、または別の 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
which を置き換えることができます。