web-dev-qa-db-ja.com

Pythonで辞書を「追加」しますか?

重複の可能性:
python dict.add_by_value(dict_2)?

私の入力は、文字列キーと整数値を持つ2つの辞書です。結果に入力辞書のすべてのキーが含まれ、値が入力辞書の値の合計になるように、2つの辞書を追加したいと思います。

わかりやすくするために、キーが入力の1つにのみ表示される場合、そのキー/値は結果に表示されますが、キーが両方の辞書に表示される場合、値の合計が結果に表示されます。

たとえば、私の入力は次のとおりです。

a = dict()
a['cat'] = 1
a['fish'] = 10
a['aardvark'] = 1000

b = dict()
b['cat'] = 2
b['dog'] = 200
b['aardvark'] = 2000

結果を次のようにしたいと思います。

{'cat': 3, 'fish': 10, 'dog': 200, 'aardvark': 3000}

Pythonこれを行うにはワンライナーが必要です(実際には1行である必要はありません...)。何か考えはありますか?

30
Roee Adler

どのようにそのことについて:

dict( [ (n, a.get(n, 0)+b.get(n, 0)) for n in set(a)|set(b) ] )

または、中間リストを作成せずに(ジェネレーターで十分です):

dict( (n, a.get(n, 0)+b.get(n, 0)) for n in set(a)|set(b) )

ポストスクリプト:

コメンテーターが正しく対処しているので、新しい(Py2.7からの)collections.Counterクラスを使用してそれを簡単に実装する方法があります。私が覚えている限り、私が答えを書いたとき、このバージョンは利用できませんでした:

from collections import Counter
dict(Counter(a)+Counter(b))
51
Juergen

結果はa

for elem in b:
    a[elem] = a.get(elem, 0) + b[elem]

結果はc

c = dict(a)
for elem in b:
    c[elem] = a.get(elem, 0) + b[elem]
15
Adrian Panasiuk

一行ではありませんが...

import itertools
import collections
a = dict()
a['cat'] = 1
a['fish'] = 10
a['aardvark'] = 1000
b = dict()
b['cat'] = 2
b['dog'] = 200
b['aardvark'] = 2000
c = collections.defaultdict(int)
for k, v in itertools.chain(a.iteritems(), b.iteritems()):
    c[k] += v

簡単に多数の辞書に拡張できます。

15
unbeknown

1つのライナー(要求されたとおり):キーリストの取得、追加、重複の破棄、リスト内包表記による結果の反復、キーが両方のdictにある場合は合計の(key、value)ペアを返す、そうでない場合は個々の値のみ。 dictでラップします。

>>> dict([(x,a[x]+b[x]) if (x in a and x in b) else (x,a[x]) if (x in a) else (x,b[x]) for x in set(a.keys()+b.keys())])
{'aardvark': 3000, 'fish': 10, 'dog': 200, 'cat': 3}
4
Markus