如何在 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 字典
  • 在 Python 中將字典新增到字典