Python PR

【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}
  • 呼び出し元の辞書自体が変更される
  • キーが被った場合は、引数の値が優先される

元の辞書を変更したくない場合、update()では余分な処理が必要になるので他の方法を試してください。

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)       # ChainMap({'a': 1, 'b': 2}, {'b': 3, 'd': 4})
print(cm['b'])  # 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)  # {'a': 1, 'b': 5, 'd': 6}
print(d2)  # {'b': 3, 'd': 4}

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

マージ演算子

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

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

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

演算子なので見た目もキレイでわかりやすい。

まとめ

この記事では、複数の辞書をマージ(結合)する方法を紹介しました。

色々な方法が用意されているので状況に合わせて選んで使ってください。特に制限がない場合は、マージ演算子を使っておけば問題ありません。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ