7

我有任意数量的具有匹配键集的等长 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}

也许有一个丑陋、复杂的循环结构,但有没有更好的方法来通过某种列表/字典理解聪明来做到这一点?想想看,我真的不知道如何制作一个丑陋的循环版本,无论如何..

4

4 回答 4

24

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

或者您可以将其更改回字典:

>>> 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]}
于 2013-10-19T02:48:13.883 回答
6

如果你只想使用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}
于 2013-10-19T06:36:13.010 回答
0

使用 sentinel 值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}
于 2021-01-26T20:15:19.383 回答
-1

这是使用带有和的字典理解的替代方法。itertools.chain.from_iterable()sum()

在这里,我正在set从所有三个字典中创建一个键。然后我在字典理解中迭代这个集合以获得每个键的的总和。

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
#   }
于 2021-01-26T20:39:53.593 回答