如何在 Python 2 和 3 中合併兩個字典

Jinku Hu 2023年1月30日
  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}
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - Python Dictionary