作者:Yong Cui, Ph.D.
翻译:老齐
与本文相关的图书推荐:《跟老齐学Python:轻松入门》
Python3.9,还在研发中,计划今年10月份发布,2月26日,研发团队发布了α版,其中有一个新功能,会关系到所有开发者,那就是两个操作符:|
和|=
,分别实现对字典的合并操作。
本文对此给予简要介绍。
字典
Python中的字典,即dict
,是一种重要的内置对象类型,它是一种以键值对方式保存数据的容器,因为使用了哈希,使得查询字典中数据时的时间复杂度恒定,这是它美名远播的一个原因。
例如:
# 创建字典
student = {'name': 'John', 'age': 14}
# 读取值
age = student['age']
# age is 14
# Update 一个值
student['age'] = 15
# student 变成 {'name': 'John', 'age': 15}
# 插入一个键值对
student['score'] = 'A'
# student 变成 {'name': 'John', 'age': 15, 'score': 'A'}
以往合并字典的方法
有时,我们需要将两个字典合并,在Python3.9之前,有几种方法可以实现。假设有两个字典:d1
和d2
,新建一个字典d3
,它的值是d1
和d2
的并集。从下面的演示中我们可以看到,如果字典中被合并的字典中有重复的键,例如d2
如果是字典d2a
那样,就会把d1
中同名的键覆盖了。
# two dicts to start with
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'd': 4}
d2a = {'a': 10, 'c': 3, 'd': 4}
# target dict
d3 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
update()
方法
第一种方法我们使用字典的update()
方法,下面的代码中演示了操作方法。注意,首先要创建d1
的拷贝,否则update()
会把原字典的值修改了。
# create a copy of d1, as update() modifies the dict in-place
d3 = d1.copy()
# d3 is {'a': 1, 'b': 2}
# update the d3 with d2
d3.update(d2)
# d3 now is {'a': 1, 'b': 2, 'c': 3, 'd': 4}
如果字典中有重名的键,我们必须更加谨慎,确定保留哪些值。如下代码所示,作为update()
方法的参数d2a
中,与d3
有重复的键,比如a
,此时会遵循“最后一个有效”的原则合并。
d3 = d1.copy()
d3.update(d2a)
# d3 now is {'a': 10, 'b': 2, 'c': 3, 'd': 4}
# This is not the way that we want d3 = d2a.copy()
d3.update(d1)
# d3 now is {'a': 1, 'c': 3, 'd': 4, 'b': 2}
# This is the way that we want
解包字典
第二种方法使用字典解包,类似上面的方法,如果有重名的键,依然是“最后一个有效”。
# unpacking
d3 = {**d1, **d2}
# d3 is {'a': 10, 'b': 2, 'c': 3, 'd': 4}
# Not right d3 = {**d2a, **d1}
# d3 is {'a': 1, 'c': 3, 'd': 4, 'b': 2}
# Good
使用dict(iterable, **kwarg)
利用dict(iterable, **kwarg)
方法创建一个字典。如果参数iterable
是一个字典,就可以创建一个同样键值对的字典,再提供另外一个字典,就可以将这个字典的键值对增加到前面字典中。注意,这个字典如果跟前面字典中有同名的参数,依然是“最后一个有效”。
d3 = dict(d1, **d2)
# d3 is {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Good, it's what we wantd3 = dict(d1, **d2a)
# d3 is {'a': 10, 'b': 2, 'c': 3, 'd': 4}
# Not right, 'a' value got replaced
注意,上面的方法只适用于以字符串为键的字典,因为它其实是以关键词传参。如果像下面这样,就会报错了。
>>> dict({'a': 1}, **{2: 3})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: keywords must be strings
>>> dict({'a': 1}, **{'2': 3})
{'a': 1, '2': 3}
合并字典的新方法
在最近发布的Python3.9.0α4中,提供了合并运算符|
,用于很方便地实现两个字典的合并,下面给出一个示例。你一定会注意到,如果两个字典中有重名的键,依然是“最后一个有效”,这与前面所看到的没有区别,比如update()
方法那样的操作。
# use the merging operator |
d3 = d1 | d2
# d3 is now {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# goodd3 = d1 | d2a
# d3 is now {'a': 10, 'b': 2, 'c': 3, 'd': 4}
# not good
与上述运算符相关的是一个增强版的运算符|=
,它的作用是对字典进行原地修改,从本质上讲,与update()
一样,以下代码段显示其用法:
# Create a copy for d1
d3 = d1.copy()
# Use the augmented assignment of the merge operator
d3 |= d2
# d3 now is {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# good
d3 |= d2a
# d3 now is {'a': 10, 'b': 2, 'c': 3, 'd': 4}
# not good
总结
本文展示了Python3.9即将发布的一个关于合并字典的运算符,此外,对asyncio
、math
、os
模块也有一些更新,迫不及待了吗?10月份Python3.9发布之时,官方文档会有详细说明,敬请查看。
原文链接:https://medium.com/better-programming/dictionary-merging-and-updating-in-python-3-9-4ac67c667ce