我的输入是两个包含字符串键和整数值的字典。我想添加两个字典,以便结果具有输入字典的所有键,并且值是输入字典值的总和。
为清楚起见,如果一个键仅出现在其中一个输入中,则该键/值将出现在结果中,而如果该键出现在两个词典中,则值的总和将出现在结果中。
例如,我的输入是:
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必须有一个单行程才能完成这项任务(它实际上不必是一行......)。有什么想法吗?
答案 0 :(得分:51)
怎么样:
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) )
Post Scriptum:
正如评论员正确解决的那样,有一种方法可以使用new(来自Py2.7)collections.Counter类来实现这一点。我记得很多,当我写下答案时,这个版本不可用:
from collections import Counter
dict(Counter(a)+Counter(b))
答案 1 :(得分:15)
结果为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]
答案 2 :(得分:15)
不是一行,而是......
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
您可以轻松地将其扩展为更多的词典。
答案 3 :(得分:4)
一个班轮(按要求排序):获取密钥列表,添加密钥列表,丢弃重复项,使用列表理解迭代结果,如果密钥在两个字符串中,则返回(密钥,值)对,或仅仅是个人如果不是。包裹在词典中。
>>> 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}