Python合并字典中的子字典,通过对值求和得到一个字典

4
我希望将字典中的所有子字典合并,同时忽略主字典键,并按值对其他字典的值进行求和。
输入:
{'first':{'a': 5}, 'second':{'a': 10}, 'third':{'b': 5, 'c': 1}}

输出:

{'a': 15, 'b': 5, 'c': 1}

我做了:

def merge_dicts(large_dictionary):
    result = {}
    for name, dictionary in large_dictionary.items():
        for key, value in dictionary.items():
            if key not in result:
                result[key] = value
            else:
                result[key] += value
    return result

这个方法是可行的,但我不认为这是一个好的方式(或不够"Pythonic")。

顺便说一下,我不喜欢我写的标题。如果有人想到更好的措辞,请编辑。


2
你唯一做得不好的事情就是遍历large_dictionary.items()而不是large_dictionary.values() - Stefan Pochmann
3个回答

6

你可以对计数器进行求和,计数器是字典子类:

>>> from collections import Counter
>>> sum(map(Counter, d.values()), Counter())
Counter({'a': 15, 'b': 5, 'c': 1})

2

这将起作用。

from collections import defaultdict
values = defaultdict(int)
def combine(d, values):
    for k, v in d.items():
        values[k] += v

for v in a.values():
    combine(v, values)

print(dict(values))

我之前在defaultdict中没有放入list,而是放了defaultdict(lambda : 0),defaultdict(int)和defaultdict(lambda : 0),但它们的结果都是一样的。不过使用int会更符合Python的风格,我也这么认为。 - daemon24
@wim 哦。嗯。我以为它会始终返回相同的列表。但它没有。等我有更多时间时,要好好思考一下这个问题。感谢您的更正。 - Stefan Pochmann
@wim 好的,我是个白痴...没想到 def f(): return [] 总是返回相同的一个。defaultdict(lambda: []) 的某些东西让我有点困惑。我猜可能是因为它看起来太像参数默认符号了。 - Stefan Pochmann

0

几乎相似,但只是短一点,我更喜欢它。

def merge_dicts(large_dictionary):
    result = {}
    for d in large_dictionary.values():
        for key, value in d.items():
            result[key] = result.get(key, 0) + value
    return result

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接