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

  1. Python 2.7 字典合并
  2. Python 3.5(及更高版本)字典合并方法
  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 ind.items()} | 0.0162378 | 2 | | dict((key, value) for d in (A, B) for key, value ind.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 ind.items()} | 0.009127499999999955 | 3 | | dict((key, value) for d in (A, B) for key, value ind.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}

相关文章 - Python dictionary

  • 如何从 Python 字典中删除元素
  • comments powered by Disqus