web-dev-qa-db-ja.com

dict要素を合計する方法

Pythonには、辞書のリストがあります:

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

すべての辞書の合計を含む最終的な辞書が1つ必要です。つまり、結果は次のようになります:{'a':5, 'b':7}

N.B:リスト内のすべての辞書には、同じ数のキーと値のペアが含まれます。

35
Nazmul Hasan

少しいですが、ワンライナー:

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

collections.Counter を使用できます

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

または、onelinersを好む場合:

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

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}

ステファンの提案を追加

>>> {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コードのバージョンは本当にうまく読み取れると思います

11
John La Rooy

これは役立つかもしれません:

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}
8
Manoj Govindan

次のコードは、それを行う1つの方法を示しています。

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 :-)

5
paxdiablo

提案されたCounterのパフォーマンスに興味があり、大きなリストのメソッドを削減し、合計しました。おそらく他の誰かもこれに興味を持っています。こちらをご覧ください: https://Gist.github.com/torstenrudolf/277e98df296f23ff921c

この辞書のリストに対して3つのメソッドをテストしました。

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

sumメソッドが最高のパフォーマンスを示し、reduceが続き、Counterが最も遅くなりました。以下に示す時間は秒単位です。

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

しかし、これは辞書の要素の数に依存しています。 sumメソッドはreduceよりも速くスローダウンします。

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}
4
trudolf

ここに合理的な美しいものがあります。

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

Python 2.7では、dictを collections.Counter オブジェクトに置き換えることができます。これにより、カウンターの加算と減算がサポートされます。

1
Dave Kirby

以下は、dict、list、arrayで機能する非常に一般的な別の有効なソリューション(python3)です。一般的でない要素の場合、元の値が出力辞書に含まれます。

def mergsum(a, b):
    for k in b:
        if k in a:
            b[k] = b[k] + a[k]
    c = {**a, **b}
    return c

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]
print(mergsum(dict1[0], dict1[1]))
1
Ste

さらに1つのラインソリューション

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

これにより、カウンターが1つだけ作成され、アキュムレーターとして使用され、最終的に辞書に変換されます。

0
Aaron McMillin