我想将两个字典合并到一个新字典中。
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = merge(x, y)
>>> z
{'a': 1, 'b': 3, 'c': 4}
每当两个字典中都存在键 k
时,只应保留值 y[k]
。
原文由 Carl Meyer 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想将两个字典合并到一个新字典中。
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = merge(x, y)
>>> z
{'a': 1, 'b': 3, 'c': 4}
每当两个字典中都存在键 k
时,只应保留值 y[k]
。
原文由 Carl Meyer 发布,翻译遵循 CC BY-SA 4.0 许可协议
在你的情况下,你可以这样做:
z = dict(list(x.items()) + list(y.items()))
这将如您所愿,将最终字典放入 z
,并使键 b
的值被第二个 ( y
dict) 正确覆盖价值:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
如果您使用 Python 2,您甚至可以删除 list()
调用。要创建 z:
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}
如果你使用 Python 3.9.0a4 或更高版本,那么你可以直接使用:
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = x | y
print(z)
{'a': 1, 'c': 11, 'b': 10}
原文由 Thomas Vander Stichele 发布,翻译遵循 CC BY-SA 4.0 许可协议
4 回答4.5k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
1 回答4.4k 阅读✓ 已解决
1 回答3.9k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
如何在一个表达式中合并两个 Python 字典?
For dictionaries
x
andy
, their shallowly-merged dictionaryz
takes values fromy
, replacing those fromx
。PEP-584
, 在此处讨论):现在:
解释
假设您有两个字典,并且希望将它们合并到一个新字典中而不更改原始字典:
期望的结果是获得一个新字典(
z
),其中的值合并,第二个字典的值覆盖第一个字典的值。在 PEP 448 中提出并 从 Python 3.5 开始提供 的新语法是
它确实是一个单一的表达方式。
请注意,我们也可以与文字符号合并:
现在:
它现在显示为在 3.5 的发布计划 PEP 478 中实现,并且它现在已进入 Python 3.5 文档中的新增功能。
但是,由于许多组织仍在使用 Python 2,您可能希望以向后兼容的方式执行此操作。在 Python 2 和 Python 3.0-3.4 中可用的经典 Pythonic 方法是分两步执行此操作:
In both approaches,
y
will come second and its values will replacex
’s values, thusb
will point to3
in our最后结果。还没有在 Python 3.5 上,但想要一个 表达式
如果您还没有使用 Python 3.5 或需要编写向后兼容的代码,并且您希望将其放在 单个表达式 中,那么最佳性能而正确的方法是将其放入函数中:
然后你有一个表达式:
您还可以创建一个函数来合并任意数量的字典,从零到非常大的数字:
此函数适用于所有字典的 Python 2 和 3。例如给定字典
a
到g
:和
g
中的键值对将优先于字典a
到f
等等。对其他答案的批评
不要使用您在以前接受的答案中看到的内容:
在 Python 2 中,您在内存中为每个 dict 创建两个列表,在内存中创建长度等于前两个加在一起的长度的第三个列表,然后丢弃所有三个列表以创建 dict。 在 Python 3 中,这将失败,因为您要添加两个
dict_items
对象,而不是两个列表 -并且您必须将它们显式创建为列表,例如
z = dict(list(x.items()) + list(y.items()))
。这是对资源和计算能力的浪费。同样,当值是不可散列的对象(例如列表)时,在 Python 3 中采用
items()
的联合(在 Python 2.7 中为viewitems()
)也会失败。即使您的值是可散列的, 由于集合在语义上是无序的,因此关于优先级的行为是未定义的。所以不要这样做:此示例演示了当值不可散列时会发生什么:
这是一个示例,其中
y
应该具有优先权,但是由于集合的任意顺序,保留了来自x
的值:您不应该使用的另一个技巧:
这使用了
dict
构造函数,并且速度非常快且内存效率很高(甚至比我们的两步过程略高),但除非您确切知道这里发生了什么(也就是说,正在传递第二个 dict作为 dict 构造函数的关键字参数),它很难阅读,它不是预期的用法,所以它不是 Pythonic。这是 在 django 中修复 的用法示例。
字典旨在采用可散列的键(例如
frozenset
s 或元组),但是 当键不是字符串时,此方法在 Python 3 中失败。该语言的创建者 Guido van Rossum 在 邮件列表 中写道:
和
我的理解(以及 语言创建者的 理解)
dict(**y)
的预期用途是为了创建字典以提高可读性,例如:代替
对评论的回应
同样,当键不是字符串时,它不适用于 3。隐式调用约定是命名空间采用普通字典,而用户必须只传递字符串形式的关键字参数。所有其他可调用对象都强制执行它。
dict
在 Python 2 中打破了这种一致性:考虑到 Python 的其他实现(PyPy、Jython、IronPython),这种不一致很糟糕。因此它在 Python 3 中得到了修复,因为这种用法可能是一个重大变化。
我向您提出,故意编写仅在一种语言版本中有效或仅在某些任意约束下有效的代码是恶意的无能。
更多评论:
我的回答是:
merge_two_dicts(x, y)
如果我们真的关心可读性,对我来说实际上似乎更清楚。而且它不向前兼容,因为 Python 2 越来越被弃用。是的。我必须让你回到这个问题,它要求对 两个 字典进行 浅层 合并,第一个的值被第二个的值覆盖 - 在一个表达式中。
假设有两个字典,一个可能会递归地将它们合并到一个函数中,但是您应该注意不要从任一源修改字典,避免这种情况的最可靠方法是在分配值时进行复制。由于键必须是可散列的,因此通常是不可变的,因此复制它们是没有意义的:
用法:
提出其他值类型的意外情况远远超出了这个问题的范围,所以我将指出 我对“字典合并字典”的规范问题的回答。
性能较差但正确的 Ad-hoc
这些方法的性能较差,但它们会提供正确的行为。它们的性能将 远低于
copy
和update
或新的解包,因为它们在更高的抽象级别上迭代每个键值对,但它们 确实 尊重优先顺序(后面的字典优先)您还可以在 dict comprehension 中手动链接字典:
或在 Python 2.6 中(可能早在 2.4 引入生成器表达式时):
itertools.chain
将以正确的顺序将迭代器链接到键值对上:性能分析
我只会对已知行为正确的用法进行性能分析。 (自包含,因此您可以自己复制和粘贴。)
在 Python 3.8.1 中,NixOS:
字典资源