返回文章列表

文章

Python合并两个相同key的字典

目录
  1. 1. 使用 update() 方法(原地修改)
  2. 2. 使用字典解包(Python 3.5+)
  3. 3. 使用 | 合并运算符(Python 3.9+)
  4. 4. 自定义合并逻辑(处理冲突)
  5. 5. 使用 collections.ChainMap(不实际合并)
  6. 6. 使用字典推导式
  7. 选择建议:

在 Python 中合并两个具有相同键(key)的字典(map),有几种常见的方法,具体取决于你希望如何处理键冲突(即两个字典中相同的键对应不同的值):

1. 使用 update() 方法(原地修改)#

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

dict1.update(dict2)
print(dict1)  # 输出: {'a': 1, 'b': 3, 'c': 4}
  • 特点:原地修改第一个字典
  • 冲突处理:第二个字典的值覆盖第一个字典的值

2. 使用字典解包(Python 3.5+)#

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

merged = {**dict1, **dict2}
print(merged)  # 输出: {'a': 1, 'b': 3, 'c': 4}
  • 特点:创建新字典,不修改原始字典
  • 冲突处理:右边的字典值覆盖左边的字典值

3. 使用 | 合并运算符(Python 3.9+)#

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

merged = dict1 | dict2
print(merged)  # 输出: {'a': 1, 'b': 3, 'c': 4}
  • 特点:语法简洁,创建新字典
  • 冲突处理:右边的字典值覆盖左边的字典值

4. 自定义合并逻辑(处理冲突)#

当需要特殊处理冲突键时(如值相加、保留列表等):

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

# 示例1:值相加
merged = {}
for key in set(dict1) | set(dict2):
    merged[key] = dict1.get(key, 0) + dict2.get(key, 0)
print(merged)  # 输出: {'a': 1, 'b': 5, 'c': 4}

# 示例2:保留列表
merged = {}
for key in set(dict1) | set(dict2):
    merged[key] = [dict1.get(key), dict2.get(key)]
print(merged)  # 输出: {'a': [1, None], 'b': [2, 3], 'c': [None, 4]}

5. 使用 collections.ChainMap(不实际合并)#

from collections import ChainMap

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

chain = ChainMap(dict1, dict2)
print(chain['a'])  # 输出: 1 (来自 dict1)
print(chain['b'])  # 输出: 2 (来自 dict1,优先使用第一个字典的值)
print(chain['c'])  # 输出: 4 (来自 dict2)
  • 特点:创建字典视图,不实际合并数据
  • 优点:内存高效,动态反映原始字典变化
  • 冲突处理:按顺序查找,返回第一个找到的值

6. 使用字典推导式#

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

# 保留 dict2 的值
merged = {k: dict2.get(k, dict1.get(k)) for k in set(dict1) | set(dict2)}
print(merged)  # 输出: {'a': 1, 'c': 4, 'b': 3}

# 保留 dict1 的值
merged = {k: dict1.get(k, dict2.get(k)) for k in set(dict1) | set(dict2)}
print(merged)  # 输出: {'a': 1, 'c': 4, 'b': 2}

选择建议:#

  1. 如果需要简单的值覆盖,使用 {**dict1, **dict2}dict1 | dict2(Python 3.9+)
  2. 如果需要特殊合并逻辑(如值相加),使用自定义循环
  3. 如果关心内存效率且不需要实际合并,使用 ChainMap
  4. 如果希望原地修改第一个字典,使用 update() 根据你的具体需求选择合适的合并方式,大多数情况下字典解包 {**d1, **d2} 是最常用且简洁的方法。