我想合并一本字典中的所有字典,同时忽略主字典的键,并按值对其他字典的值求和。
输入:
{'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
它确实有效,但我不认为这是一个好方法(或者不太“Python化”)。
顺便说一句,我不喜欢我写的标题。如果有人想到更好的措辞,请修改。
你的代码确实有效,但可以用更“Pythonic”的方法来实现,减少显式的逻辑和循环。下面是几种优化的解决方案:
collections.Counter
Counter 是一个专门用于计数的字典子类,可以很好地解决你的问题。
Counter
from collections import Counter def merge_dicts(large_dictionary): result = Counter() for subdict in large_dictionary.values(): result.update(subdict) return dict(result) # 输入 input_dict = {'first': {'a': 5}, 'second': {'a': 10}, 'third': {'b': 5, 'c': 1}} # 输出 output = merge_dicts(input_dict) print(output) # {'a': 15, 'b': 5, 'c': 1}
使用 Counter.update 方法可以直接累加字典的值,避免显式地检查键是否存在。
Counter.update
defaultdict
defaultdict 可以让你在访问字典时自动初始化键的值。
from collections import defaultdict def merge_dicts(large_dictionary): result = defaultdict(int) for subdict in large_dictionary.values(): for key, value in subdict.items(): result[key] += value return dict(result) # 输入 input_dict = {'first': {'a': 5}, 'second': {'a': 10}, 'third': {'b': 5, 'c': 1}} # 输出 output = merge_dicts(input_dict) print(output) # {'a': 15, 'b': 5, 'c': 1}
functools.reduce
如果你喜欢函数式编程,可以尝试 reduce 和字典解包来实现累加。
reduce
from functools import reduce def merge_dicts(large_dictionary): return reduce( lambda acc, subdict: {k: acc.get(k, 0) + subdict.get(k, 0) for k in set(acc) | set(subdict)}, large_dictionary.values(), {} ) # 输入 input_dict = {'first': {'a': 5}, 'second': {'a': 10}, 'third': {'b': 5, 'c': 1}} # 输出 output = merge_dicts(input_dict) print(output) # {'a': 15, 'b': 5, 'c': 1}
尽管这个方法功能强大,但它的可读性可能不如前两种方法。
如果你想要一个简短的实现,可以用字典生成器和嵌套循环实现:
def merge_dicts(large_dictionary): result = {} for subdict in large_dictionary.values(): for key, value in subdict.items(): result[key] = result.get(key, 0) + value return result # 输入 input_dict = {'first': {'a': 5}, 'second': {'a': 10}, 'third': {'b': 5, 'c': 1}} # 输出 output = merge_dicts(input_dict) print(output) # {'a': 15, 'b': 5, 'c': 1}
对于小字典来说,性能差异不大,但对于较大的字典,Counter 和 defaultdict 通常更高效。