Python

【Python】2つの辞書を1つにする方法【マージ】

この記事では、Pythonの辞書をマージする方法を紹介します。

マージとは、複数あるものを1つにすることを言います。Python 3.9では、辞書をマージできる演算子も追加されました。

是非とも使い方を知っておきましょう!

updateメソッド

dict型のupdate()メソッドを使うことで辞書をマージすることができる。

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

d1.update(d2)

print(d1)

実行結果

{'a': 1, 'b': 3, 'd': 4}
  • 元の辞書自体が変更される
  • キーが被った場合は、引数の値が優先される

元の辞書を変更したくない場合は、一時変数を使う。

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

# 一時変数にd1をコピー
temp = d1.copy()
# 一時変数をupdate
temp.update(d2)

print(temp)

dictコンストラクタ

dict()の第一引数に辞書、第二引数にキーワード引数として展開した辞書を渡すことでマージできます。

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

d3 = dict(d1, **d2)

print(d3)

実行結果

{'a': 1, 'b': 3, 'd': 4}
  • 新たな辞書を生成できる
  • キーが被った場合は、キーワード引数の値が優先される
  • d2が文字列キーしか持たない場合にのみ使用可能

{**d1, **d2}

Python 3.5以上で使用可能

辞書リテラルに展開した辞書を渡すことでマージすることができます。

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

d3 = {**d1, **d2}

print(d3)

実行結果

{'a': 1, 'b': 3, 'd': 4}
  • 新たな辞書を生成できる
  • キーが被った場合は、後者に指定した辞書の値が優先される
  • 見た目が汚い

collections.ChainMap

標準ライブラリであるcollectionsモジュールのChainMapクラスを使うことでマージできます。

LinkChainMap - collections --- コンテナデータ型 — Python ドキュメント

from collections import ChainMap

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

cm = ChainMap(d1, d2)

print(cm)
print(cm['b'])

実行結果

ChainMap({'a': 1, 'b': 2}, {'b': 3, 'd': 4})
2
  • update()を繰り返すより高速
  • 参照を使っているので元の辞書にも影響を与える
  • キーが被った場合は、前者に指定した辞書の値が優先

以下のように書き換えた場合は、元の辞書の値も変わってしまいます。

from collections import ChainMap

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}

cm = ChainMap(d1, d2)

# 書き換える
cm['b'] = 5
cm['d'] = 6

print(d1)
print(d2)

実行結果

{'a': 1, 'b': 5, 'd': 6}
{'b': 3, 'd': 4}

更新は最初に指定した辞書のみ行われる。もし、2つ目以降の辞書を更新したい場合は、サブクラスを作成することで実現できる。

マージ演算子

Python 3.9以上で使用可能

|または|=を使うことで簡単に辞書をマージできるようになりました。

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'd': 4}
print(d1 | d2)

d1 |= d2
print(d1)

実行結果

{'a': 1, 'b': 3, 'd': 4}
{'a': 1, 'b': 3, 'd': 4}
  • キーが被った場合は、後者に指定した辞書の値が優先