本記事では、Pythonで辞書を結合する方法を解説します。辞書を結合する方法はいくつかあり、その中でも主な方法を説明します。辞書の結合は複数のデータソースを統合する際や、設定情報をマージする場合など、多くの実践的なシナリオで必要となる操作です。
update
update()メソッドは、Pythonの辞書に組み込まれたメソッドで、ある辞書の内容を別の辞書に追加することができます。元の辞書が更新されるため、破壊的操作になります。メモリ効率が良く、既存の辞書を直接更新したい場合に適しています。
構文
dict1.update(dict2)
コード例
以下のコードではupdate()メソッドを使って2つの辞書を結合しています。dict1にdict2の内容が追加されます。この方法は元の辞書を直接変更するため、新しい変数を作成する必要がない場合に便利です。
dict1 = {"name": "太郎", "age": 30}
dict2 = {"city": "東京", "job": "エンジニア"}
dict1.update(dict2)
print(dict1)
# 出力: {'name': '太郎', 'age': 30, 'city': '東京', 'job': 'エンジニア'}
# キーが重複する場合は上書きされる
dict3 = {"name": "太郎", "age": 30}
dict4 = {"age": 25, "hobby": "読書"}
dict3.update(dict4)
print(dict3)
# 出力: {'name': '太郎', 'age': 25, 'hobby': '読書'}
注意点
update()メソッドは元の辞書を直接変更するため、元のデータが必要な場合は事前にコピーを作成しておく必要があります。キーが重複する場合は常に新しい値で上書きされるため、意図しないデータの損失が発生する可能性があります。
以下はネストされた辞書を結合する場合の例です。ネストされた辞書は完全に上書きされることに注意してください。
dict1 = {
"name": "太郎",
"age": 30,
"address": {
"city": "東京",
"area": "新宿"
}
}
dict2 = {
"job": "エンジニア",
"address": {
"city": "大阪",
"zip": "530-0001"
}
}
dict1.update(dict2)
print(dict1)
# 出力: {'name': '太郎', 'age': 30, 'address': {'city': '大阪', 'zip': '530-0001'}, 'job': 'エンジニア'}
# 'address'キーの値が完全に上書きされ、'area'の情報が失われている
展開演算子(**)
展開演算子(**)を使うと、辞書の内容を別の辞書リテラル内に展開できます。新しい辞書を作成するため、元の辞書は変更されません。この方法は元のデータを保持したまま新しい辞書を作成したい場合に最適で、Python 3.5以降で使用できます。
構文
merged_dict = {**dict1, **dict2}
コード例
以下のコードでは展開演算子を使って複数の辞書を結合しています。新しい辞書が作成されるため、元の辞書は変更されません。この方法は複数の辞書を一度に結合する場合に特に便利です。
dict1 = {"name": "太郎", "age": 30}
dict2 = {"city": "東京", "job": "エンジニア"}
merged_dict = {**dict1, **dict2}
print(merged_dict)
# 出力: {'name': '太郎', 'age': 30, 'city': '東京', 'job': 'エンジニア'}
# キーが重複する場合は後の辞書の値が優先される
dict3 = {"name": "太郎", "age": 30}
dict4 = {"age": 25, "hobby": "読書"}
merged_dict = {**dict3, **dict4}
print(merged_dict)
# 出力: {'name': '太郎', 'age': 25, 'hobby': '読書'}
# 3つ以上の辞書も結合可能
dict5 = {"status": "学生"}
merged_dict = {**dict3, **dict4, **dict5}
print(merged_dict)
# 出力: {'name': '太郎', 'age': 25, 'hobby': '読書', 'status': '学生'}
注意点
展開演算子はPython 3.5以降でしか使用できないため、古いバージョンのPythonでは動作しません。また、ネストされた辞書の場合、最上位レベルのキーのみがマージされ、ネストされた辞書は上書きされます。
|演算子(Python3.9以降)
Python 3.9から導入された|演算子(マージ演算子)を使って辞書を結合することができます。新しい辞書を作成するため、元の辞書は変更されません。この演算子は展開演算子よりも簡潔で直感的な構文を提供し、コードの可読性を向上させます。
構文
merged_dict = dict1 | dict2
コード例
以下のコードでは|演算子を使って辞書を結合しています。簡潔で読みやすい構文が特徴です。また、|=演算子を使うことで、update()メソッドと同様の更新操作も可能です。
# Python 3.9以降で実行可能
dict1 = {"name": "太郎", "age": 30}
dict2 = {"city": "東京", "job": "エンジニア"}
merged_dict = dict1 | dict2
print(merged_dict)
# 出力: {'name': '太郎', 'age': 30, 'city': '東京', 'job': 'エンジニア'}
# キーが重複する場合は右側の辞書の値が優先される
dict3 = {"name": "太郎", "age": 30}
dict4 = {"age": 25, "hobby": "読書"}
merged_dict = dict3 | dict4
print(merged_dict)
# 出力: {'name': '太郎', 'age': 25, 'hobby': '読書'}
# |=演算子を使うと更新も可能
dict5 = {"name": "花子", "status": "学生"}
dict5 |= dict4
print(dict5)
# 出力: {'name': '花子', 'status': '学生', 'age': 25, 'hobby': '読書'}
注意点
|演算子はPython 3.9以降でしか使用できないため、古いバージョンのPythonを使用している環境では動作しません。展開演算子と同様に、ネストされた辞書の場合は最上位レベルのキーのみがマージされます。
dict()コンストラクタと展開演算子の組み合わせ
dict()コンストラクタと展開演算子を組み合わせることで、辞書を結合する別の方法も提供されています。この方法は特に複数の辞書を結合する場合に便利です。
構文
merged_dict = dict(**dict1, **dict2)
コード例
以下のコードではdict()コンストラクタと展開演算子を組み合わせて辞書を結合しています。この方法は特に関数の引数として辞書を渡す場合に役立ちます。
dict1 = {"name": "太郎", "age": 30}
dict2 = {"city": "東京", "job": "エンジニア"}
merged_dict = dict(**dict1, **dict2)
print(merged_dict)
# 出力: {'name': '太郎', 'age': 30, 'city': '東京', 'job': 'エンジニア'}
# キーが重複する場合は後の辞書の値が優先される
dict3 = {"name": "太郎", "age": 30}
dict4 = {"age": 25, "hobby": "読書"}
merged_dict = dict(**dict3, **dict4)
print(merged_dict)
# 出力: {'name': '太郎', 'age': 25, 'hobby': '読書'}
注意点
この方法も展開演算子を使用するため、Python 3.5以降でしか使用できません。関数呼び出しのオーバーヘッドがあるため、大量の辞書を結合する場合はパフォーマンスが低下する可能性があります。展開演算子と同様に、ネストされた辞書の場合は最上位レベルのキーのみがマージされ、ネストされた辞書は上書きされます。
まとめ
Pythonで辞書を結合する方法はいくつかあります:
- update()メソッド – 既存の辞書を更新する破壊的操作
- 展開演算子(**) – 新しい辞書を作成する非破壊的操作
- |演算子 – Python 3.9以降で使用可能な、より簡潔な非破壊的操作
- dict()コンストラクタと展開演算子 – 特に関数の引数として使用する場合に便利
各方法の特徴と使い分けは以下の通りです:
方法 | バージョン要件 | 元の辞書の変更 | 特徴 | 適した用途 |
---|---|---|---|---|
update() | すべて | あり(破壊的) | メモリ効率が良い | 既存の辞書を更新する場合、パフォーマンスが重要な場合 |
展開演算子(**) | Python 3.5+ | なし(非破壊的) | 複数の辞書を一度に結合可能 | 元のデータを保持したい場合、複数の辞書を結合する場合 |
|演算子 | Python 3.9+ | なし(非破壊的) | 簡潔で直感的な構文 | 新しいバージョンのPythonを使用している場合、コードの可読性を重視する場合 |
dict()と展開演算子 | Python 3.5+ | なし(非破壊的) | 関数呼び出しに適している | 関数の引数として辞書を渡す場合 |
用途や状況に合わせて最適な方法を選ぶとよいでしょう。新しいバージョンのPythonを使用している場合は、読みやすさの観点から|演算子がおすすめです。また、パフォーマンスが重要な場合はupdate()メソッドが、元のデータを保持したい場合は展開演算子や|演算子が適しています。
すべての方法に共通する注意点として、ネストされた辞書を結合する場合、最上位レベルのキーのみがマージされ、深いレベルの辞書は上書きされます。深くネストされた辞書を適切に結合するには、専用のライブラリや再帰的な結合関数の使用を検討するとよいでしょう。