如何在 Python 2 和 3 中合并两个字典

Jinku Hu 2023年1月30日 2019年12月26日
  1. Python 2.7 字典合并
  2. Python 3.5(及更高版本)字典合并方法
  3. 合并方法结论
如何在 Python 2 和 3 中合并两个字典

假设我们有两个字典 AB 需要进行合并,其中 B 的值将取代 A 的值,如果它们有相同的键 key 的话。

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}

Python dictionary 对象有一个原生方法 update() 来用 B 来更新字典 A

A.update(B)

但是 A 的数据将被替换,而不是返回包含合并 AB 的新字典。

我们将介绍如何合并两个字典并返回新字典的方法。

Python 2.7 字典合并

字典推导式方法-1

C = {key: value for d in (A, B) for key, value in d.items()}

d.itmes() 以字典 d 的 2 元组的形式返回 (key, value) 对的列表。

此方法使用嵌套字典推导式合并两个字典。for 的正确顺序应格外注意。它应该是,

flattern_patterns = [planet
                    for sublist in planets
                    for planet in sublist]

字典推导式方法-2

我们还可以使用 dict() 方法来初始化新字典。

C = dict((key, value) for d in (A, B) for key, value in d.items())

从技术上讲,它与上述方法几乎相同,但是在性能上有所不同,我们将在后面提到。

itertools.chain 方法

itertools 模块标准化了一组核心 iterator 构建块。它具有快速和高效存储等功能。

itertools.chain 返回一个链对象,该对象的 .next() 方法从第一个可迭代对象返回元素,直到用尽为止,然后从下一个可迭代对象返回元素,直到所有元素用尽。

dict(itertools.chain(A.iteritems(), B.iteritems()))

iteritems() 返回字典 (key, value) 元素的迭代器。

因此,以上脚本将返回包含 AB 元素的字典。

copyupdate 方法

如开头所述,update 可以合并 AB,但是将就地替换字典。我们可以使用 copy 方法复制字典 A

m = A.copy()
C = m.update(B)

合并方法性能分析和比较

import timeit

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}

SETUP_CODE = '''
A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
'''

TEST_CODE = '''
{key: value for d in (A, B) for key, value in d.items()}
'''
print min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000))

TEST_CODE = '''
dict((key, value) for d in (A, B) for key, value in d.items())
'''
print min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000))

TEST_CODE = '''
dict(itertools.chain(A.iteritems(), B.iteritems()))
'''
print min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000))

SETUP_CODE = '''
def merge_dicts(a, b):
    m = a.copy()
    m.update(b)
    return m

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
'''

TEST_CODE = '''
merge_dicts(A, B)
'''
print min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000))

结果是

0.0162378
0.029774
0.019975
0.0110059
方法 性能 排名
{key: value for d in (A, B) for key, value in d.items()} 0.0162378 2
dict((key, value) for d in (A, B) for key, value in d.items()) 0.029774 4
dict(itertools.chain(A.iteritems(), B.iteritems())) 0.019975 3
merge_dicts(a, b) 0.0110059 1

Python 3.5(及更高版本)字典合并方法

从 Python 3.5 开始,除了与 Python 2.7 中相同的方法外,它还具有 PEP-448 中 引入的 ** unpacking 运算符。它可以解压缩任意数量的 dictionary 对象。

注意
d.iteritems() 在 Python 3 中已弃用。请参阅 PEP-469
>>> C = {**A, **B}
>>> C
{'x': 10, 'y': 30, 'z': 40}
import timeit

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}

SETUP_CODE = '''
A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
'''

TEST_CODE = '''
{**A, **B}
'''
print(min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000)))

TEST_CODE = '''
{key: value for d in (A, B) for key, value in d.items()}
'''
print(min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000)))

TEST_CODE = '''
dict((key, value) for d in (A, B) for key, value in d.items())
'''
print(min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000)))

TEST_CODE = '''
dict(itertools.chain(A.items(), B.items()))
'''
print(min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000)))

SETUP_CODE = '''
def merge_dicts(a, b):
    m = a.copy()
    m.update(b)
    return m

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
'''

TEST_CODE = '''
merge_dicts(A, B)
'''
print(min(timeit.repeat(setup = SETUP_CODE, stmt = TEST_CODE, repeat = 3, number=10000)))
0.0017047999999999508
0.009127499999999955
0.0168952
0.01078009999999996
0.005767999999999995
方法 性能 排名
{**A, **B} 0.0017047999999999508 1
{key: value for d in (A, B) for key, value in d.items()} 0.009127499999999955 3
dict((key, value) for d in (A, B) for key, value in d.items()) 0.0168952 5
dict(itertools.chain(A.items(), B.items())) 0.01078009999999996 4
merge_dicts(a, b) 0.005767999999999995 2

合并方法结论

在 Python 2.7,copyupdate 是最好的方法。

m = A.copy()
C = m.update(B)

在 Python 3.5+ 中,字典解压缩方法是最好的。

{**A, **B}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - Python Dictionary