Python 2 および 3 で 2つの辞書をマージする方法

マージする 2つの辞書 A
と B
があり、B
の値が同じ key
を共有している場合、A
の値を置き換えると仮定します。
A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
Python の dictionary
オブジェクトには、辞書 A
を B
で更新するための組み込みメソッド update()
メソッドがあります。
A.update(B)
ただし、A
と B
のマージを含む新しい辞書を返す代わりに、A
のデータはその場で置き換えられます。
2つの辞書をマージして新しい辞書を返す方法を紹介します。
Python 2.7 辞書マージ
辞書内包表記法-1
C = {key: value for d in (A, B) for key, value in d.items()}
d.itmes()
は、(key, value)
のペアのリストを辞書 d
の 2 タプルとして返します。
このメソッドは、ネストされた辞書内包表記を使用して 2つの辞書をマージします。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)
アイテムのイテレータを返します。
したがって、上記のスクリプトは、A と B のアイテムを含む辞書を返します。
copy
および update
メソッド
冒頭で述べたように、update()
は A
と B
をマージできますが、辞書をその場で置き換えます。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。任意の数のアイテムをアンパックできます。
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 では、copy
と update
が最適な方法です。
m = A.copy()
C = m.update(B)
Python 3.5 以降では、辞書の展開方法が最適です。
{**A, **B}
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