私の入力は、文字列キーと整数値を持つ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行である必要はありません...)。何か考えはありますか?
どのようにそのことについて:
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))
結果は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]
一行ではありませんが...
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
簡単に多数の辞書に拡張できます。
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}