我有一组任意数量的等长python词典,带有匹配的键组,如下所示:
{'a':1, 'b':4, 'c':8, 'd':9}
{'a':2, 'b':3, 'c':2, 'd':7}
{'a':0, 'b':1, 'c':3, 'd':4}
...
如何使用相同的键集获取单个字典,但是将值作为字典集中相应元素的总和?换句话说,我想要:
{'a':3, 'b':8, 'c':13, 'd':20}
也许有一个丑陋,复杂的循环结构,但有一种更好的方法来做某些列表/字典理解聪明吗?想想看,我真的不确定如何制作一个丑陋的循环版本,无论如何..
答案 0 :(得分:15)
collections.Counter()
救援; - )
from collections import Counter
dicts = [{'a':1, 'b':4, 'c':8, 'd':9},
{'a':2, 'b':3, 'c':2, 'd':7},
{'a':0, 'b':1, 'c':3, 'd':4}]
c = Counter()
for d in dicts:
c.update(d)
然后:
>>> print c
Counter({'d': 20, 'c': 13, 'b': 8, 'a': 3})
或者你可以将它改回dict:
>>> print dict(c)
{'a': 3, 'c': 13, 'b': 8, 'd': 20}
Counter()
所有输入词都是否具有相同的键并不重要。如果你肯定知道他们这样做,你可以尝试荒谬;-)这样的单行:
d = {k: v for k in dicts[0] for v in [sum(d[k] for d in dicts)]}
Counter()
更清晰,更快捷,更灵活。但公平地说,这种略显荒谬的单行内容并不那么荒谬:
d = {k: sum(d[k] for d in dicts) for k in dicts[0]}
答案 1 :(得分:2)
如果您只想使用dict
,则可以使用此
dicts = [{'a':0, 'b':4, 'c':8, 'd':9},
{'a':0, 'b':3, 'c':2, 'd':7},
{'a':0, 'b':1, 'c':3, 'd':4}]
result = {}
for myDict in dicts:
for key, value in myDict.items():
result.setdefault(key, 0)
result[key] += value
print result
<强>输出:强>
{'a': 0, 'c': 13, 'b': 8, 'd': 20}
答案 2 :(得分:0)
使用 sum
的哨兵值作为 Counter
对象的单行:
>>> from collections import Counter
>>> dicts = [{'a':1, 'b':4, 'c':8, 'd':9},
{'a':2, 'b':3, 'c':2, 'd':7},
{'a':0, 'b':1, 'c':3, 'd':4}]
>>> dict(sum(map(Counter, dicts), start=Counter()))
{'a': 3, 'b': 8, 'c': 13, 'd': 20}
答案 3 :(得分:-1)
这是将字典理解与itertools.chain.from_iterable()
和sum()
一起使用的替代方法。
在这里,我正在从所有三个字典中创建一个 set
键。然后我在 dictionary comprehension 中迭代这个集合以获得每个 key 的 values 总和。
from itertools import chain
my_dicts = [
{'a':1, 'b':4, 'c':8, 'd':9},
{'a':2, 'b':3, 'c':2, 'd':7},
{'a':0, 'b':1, 'c':3, 'd':4}
]
new_dict = {k: sum(dd.get(k, 0) for dd in my_dicts) for k in set(chain.from_iterable(d.keys() for d in my_dicts))}
# where `new_dict` will hold:
# {
# 'a': 3,
# 'b': 8,
# 'c': 13,
# 'd': 20
# }