返回

合并字典的 Pythonic 方法:如何相加相同键的值?

python

合并字典的 Pythonic 方法

在 Python 中合并字典看起来很简单,对吧?使用 update() 方法即可。但是,当涉及到具有相同键的字典时,事情就变得棘手了。update() 倾向于用后一个字典的值覆盖前一个字典中的值,但我们希望将它们相加。

1. Counter 类

一个 Pythonic 方法是使用 Counter 类。它用于计数元素的出现,但它有一个神奇的 update() 方法,可以将另一个 Counter 实例中的值相加。

步骤:

  1. 将字典转换为 Counter 实例。
  2. 使用 update() 将第二个实例添加到第一个中。
  3. 将合并后的 Counter 转换为字典。
from collections import Counter

dict_a = {'a': 1, 'b': 2, 'c': 3}
dict_b = {'b': 3, 'c': 4, 'd': 5}

counter_a = Counter(dict_a)
counter_b = Counter(dict_b)

counter_a.update(counter_b)

combined_dict = dict(counter_a)

2. defaultdict 类

另一个选择是使用 defaultdict 类。它创建一个字典,其中不存在的键自动获得默认值。我们可以使用它来汇总值。

步骤:

  1. 创建一个 defaultdict,默认值为 0。
  2. 遍历第一个字典并将其键值对添加到 defaultdict 中。
  3. 遍历第二个字典并将其键值对添加到 defaultdict 中,同时将值相加。
from collections import defaultdict

dict_a = {'a': 1, 'b': 2, 'c': 3}
dict_b = {'b': 3, 'c': 4, 'd': 5}

combined_dict = defaultdict(int)

for key, value in dict_a.items():
    combined_dict[key] += value

for key, value in dict_b.items():
    combined_dict[key] += value

3. zip() 和 operator.add()

最后,我们可以利用 zip()operator.add() 函数。

步骤:

  1. 将键和值解压缩为单独的列表。
  2. 使用 zip() 组合它们,并使用 operator.add() 相加相同键的值。
  3. 将合并后的键和值对转换为字典。
import operator

dict_a = {'a': 1, 'b': 2, 'c': 3}
dict_b = {'b': 3, 'c': 4, 'd': 5}

keys_a, values_a = zip(*dict_a.items())
keys_b, values_b = zip(*dict_b.items())

combined_keys = [key for key in keys_a if key in keys_b]
combined_values = [operator.add(value_a, value_b) for value_a, value_b in zip(values_a, values_b) if value_a + value_b]

combined_dict = dict(zip(combined_keys, combined_values))

选择哪种方法?

  • Counter 类: 最快捷、最简单,仅适用于整数。
  • defaultdict 类: 更通用,但不那么简洁。
  • zip()operator.add() 最通用,但最复杂。

常见问题解答

  1. 为什么使用 update() 存在问题?
    • update() 用后一个字典的值覆盖前一个字典的值。
  2. Counter 类有其他用途吗?
    • 是的,它还用于统计字符串、列表或元组中的元素出现次数。
  3. defaultdict 类中默认值为何必须是 0?
    • 这不是必需的,你可以指定任何默认值。0 只是最常见的。
  4. zip() 函数和 operator.add() 函数有何区别?
    • zip() 组合列表,operator.add() 相加值。
  5. 我应该在什么时候使用这些方法?
    • 当你想要合并具有相同键的字典并相加值时,请使用这些方法。