【问题标题】:Merging two dictionaries while keeping both the original and the new value for each key合并两个字典,同时保留每个键的原始值和新值
【发布时间】:2016-07-10 21:25:17
【问题描述】:

在 Python 中,当我使用 update() 方法合并两个字典时,任何现有的键都将被覆盖。

有没有办法合并两个字典,同时在合并结果中保留原始键?

假设我们有以下示例:

dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3}
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5}

我们可以合并两个字典,这样结果将保留键 bookC 的两个值吗?

我希望dict3 看起来像这样:

{'bookA': 1, 'bookB': 2, 'bookC': (2,3), 'bookD': 4, 'bookE': 5}

【问题讨论】:

  • 你能提供一个示例输入/输出吗?
  • 您希望对两个字典中都存在的键发生什么情况?
  • @BAH 谢谢,添加了一个例子
  • 您不能让字典包含两个具有相同值的键。键必须是唯一的。我会质疑外部代码的用途以及字典是否是存储所需数据的正确对象?

标签: python dictionary merge


【解决方案1】:
a = {'a': 1, 'b': 2, 'c': 3}
b = {'a': 10, 'd': 2, 'e': 3}

for k in b:
    if k not in a:
        a[k] = b[k]

更新

更新问题后,我同意 BAH 使用带有列表的 defaultdict 的实现

【讨论】:

  • "我们是否可以合并两个字典,这样结果会保留键 bookC 的 两个值?"
  • 好的,但它不能回答目前的问题。有时会发生编辑问题以使答案无效的情况。该答案应该更改或删除。
【解决方案2】:

如果可以将所有值保留为一个列表(我更喜欢这样,当您的值数据类型不一致时,它只会增加额外的头痛和逻辑),您可以使用以下方法使用 @ 更新示例987654321@

from itertools import chain
from collections import defaultdict

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 2, 'b': 3, 'd': 4}

d3 = defaultdict(list)

for k, v in chain(d1.items(), d2.items()):
    d3[k].append(v)

for k, v in d3.items():
    print(k, v)

打印:

a [1, 2]
d [4]
c [3]
b [2, 3]

您也有以下方法,我觉得它的可读性有点差:

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 2, 'b': 3,}

d3 = dict((k, [v] + ([d2[k]] if k in d2 else [])) for (k, v) in d1.items())

print(d3)

这不会修改任何原始字典并打印:

{'b': [2, 3], 'c': [3], 'a': [1, 2]}

【讨论】:

  • d2 中没有 d1 的元素怎么办?他们会通过上述实现进入 d3 吗?
  • @EduardoCMB 你是对的他们不会,我意识到当他更新他的问题时。使用defaultdict查看编辑后的答案
  • 这正是我刚刚写的——但*zip 调用是多余的。也只需使用d3[k].append(v)
  • @Simplicity,不用担心,很高兴能帮上忙 :)
  • 一行呢?
【解决方案3】:
a = {'a': 1, 'b': 2, 'c': 3}
b = {'a': 10, 'd': 2, 'e': 3}

b.update({key: (a[key], b[key]) for key in set(a.keys()) & set(b.keys())})
b.update({key: a[key] for key in set(a.keys()) - set(b.keys())})

print(b)

输出: {'c': 3, 'd': 2, 'e': 3, 'b': 2, 'a': (1, 10)}

【讨论】:

  • 输出应该有ab的键
【解决方案4】:

还有另一种方法可以将所有值保存为一个列表,它不使用 defaultdict 或链。

修改示例:

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 2, 'b': 3, 'd': 4}
d3 = {}
for (k, v) in list(d1.items())+list(d2.items()):
    try:
        d3[k] += [v]
    except KeyError:
        d3[k] = [v]
print(d3)

那么我们有:

{'d': [4], 'b': [2, 3], 'a': [1, 2], 'c': [3]}

try 语句用于提高速度。 它尝试将值 v 与键 k 相加。 在 KeyError 的情况下,d3 接受新的密钥。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-03
    • 2023-03-28
    • 1970-01-01
    • 2022-12-12
    • 2019-03-23
    • 2016-06-20
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多