如何在 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