Pythonで辞書同士を結合(連結・マージ)

Posted: | Tags: Python, 辞書

Pythonで、複数の辞書(dict)を結合(連結・マージ)する方法について説明する。

辞書に個別の要素(キーkeyと値value)を追加・更新する方法については以下の記事を参照。

複数の辞書を結合して新たな辞書を生成

dict(), {}

辞書の生成に使われるdict()および{}では、**をつけて複数の辞書を指定できる。例は辞書2つだが、3つ以上でもよい。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k3': 3, 'k4': 4}

d = dict(**d1, **d2)
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}

d = {**d1, **d2}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}

引数に指定する複数の辞書のキーが重複している場合、dict()ではエラーになるので注意。{}では後ろ(右側)の辞書の値で上書きされる。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}

# d = dict(**d1, **d2)
# TypeError: dict() got multiple values for keyword argument 'k1'

d = {**d1, **d2}
print(d)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4}

辞書の生成についての詳細は以下の記事を参照。

|演算子(Python3.9以降)

Python3.9から|演算子で2つの辞書を結合(マージ)できるようになった。重複するキーがある場合は右側の値で上書きされる。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}

d = d1 | d2
print(d)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4}

d = d2 | d1
print(d)
# {'k1': 1, 'k3': 3, 'k4': 4, 'k2': 2}

|演算子を連続して使うと、複数の辞書を結合可能。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}
d3 = {'k5': 5, 'k6': 6}

d = d1 | d2 | d3
print(d)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6}

既存の辞書に別の辞書を結合

update()

辞書のupdate()メソッドの引数に別の辞書を指定すると、辞書が結合される。

既存のキーと重複する場合は引数に指定した辞書の値で上書きされる。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}

d1.update(d2)
print(d1)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4}

update()の引数に複数の辞書をそのまま指定するとエラーとなる。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}
d3 = {'k5': 5, 'k6': 6}

# d1.update(d2, d3)
# TypeError: update expected at most 1 arguments, got 2

update()ではキーワード引数(key=value)で新たな要素を追加できるので、辞書に**をつけてそれぞれの要素をキーワード引数として展開して渡せばよい。

d1.update(**d2, **d3)
print(d1)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6}

**を使う場合、上の例のように、呼び出し元の辞書と引数に指定する辞書のキーが重複しているのは問題ないが、引数に指定する複数の辞書のキーが重複しているとエラーになるので注意。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}
d3 = {'k5': 5, 'k6': 6}

# d3.update(**d1, **d2)
# TypeError: dict.update() got multiple values for keyword argument 'k1'

update()で個別に要素を追加する場合の詳細は以下の記事を参照。

|=演算子(Python3.9以降)

上述のように、Python3.9から|演算子で2つの辞書を結合(マージ)できるようになった。

+演算子における+=演算子のように、|=演算子で累算代入が可能。update()と同様に、左辺のオブジェクトに右辺のオブジェクトが結合され更新される。

d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3, 'k4': 4}

d1 |= d2
print(d1)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4}

なお、|=演算子では、(key, value)のリストのような、キーと値のペア(2要素のイテラブル)のイテラブルも右辺に指定できる。

d = {'k1': 1, 'k2': 2}

d |= [('k1', 100), ('k3', 3), ('k4', 4)]
print(d)
# {'k1': 100, 'k2': 2, 'k3': 3, 'k4': 4}

|演算子ではそのようなイテラブルを指定するとエラーになるので注意。辞書同士の演算のみがサポートされている。

# d | [('k1', 100), ('k3', 3), ('k4', 4)]
# TypeError: unsupported operand type(s) for |: 'dict' and 'list'

関連カテゴリー

関連記事