小能豆

Python通过对值求和将字典中的字典合并为一个字典

py

我想合并一本字典中的所有字典,同时忽略主字典的键,并按值对其他字典的值求和。

输入:

{'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化”)。

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


阅读 11

收藏
2024-11-19

共1个答案

小能豆

你的代码确实有效,但可以用更“Pythonic”的方法来实现,减少显式的逻辑和循环。下面是几种优化的解决方案:


1. 使用 collections.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 方法可以直接累加字典的值,避免显式地检查键是否存在。


2. 使用 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}

3. 使用 functools.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}

尽管这个方法功能强大,但它的可读性可能不如前两种方法。


4. 使用单行字典生成器

如果你想要一个简短的实现,可以用字典生成器和嵌套循环实现:

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}

5. 对比性能

对于小字典来说,性能差异不大,但对于较大的字典,Counterdefaultdict 通常更高效。


推荐

  • 如果你想要简单、Pythonic 且高效的实现,使用 collections.Counter 是最佳选择
  • 如果需要控制更多逻辑,defaultdict 提供了灵活性。
2024-11-19