この記事は最終更新日から1年以上が経過しています。
Pythonで次のような2つの辞書型をマージしたいケースがありました。
dict_a = { 'A': 'A', 'B': { 'C':'C', 'D':'D', 'E': { 'F':'F', 'G':'G' } }, 'H': ['I','J'], 'L': [{'M': 'M', 'N': 'N'}, {'O':'O'}] } dict_b = { 'A': 'a', 'B': { 'C':'c', 'E': { 'F':'f', } }, 'H': ['k'], 'L': [{'N': 'n'}, {'P':'p'}] } |
マージする方法を調べていると、以下のようなやりかたがあります。
1. 新規につくる方法
print(dict(dict_a, **dict_b)) |
実行結果はこうなります
{'B': {'C': 'c', 'E': {'F': 'f'}}, 'L': [{'N': 'n'}, {'P': 'p'}], 'A': 'a', 'H': ['k']} |
しかし、実行結果をよく見ると、dict_a[‘B’][‘D’] や dict_a[‘B’][‘E’][‘G’] がなくなっています。
実行結果から考えると入れ子になっているところはマージしてくれないようです。
他にも調べてみましたが、いい感じにマージする方法がないようなので、実装しました。
import copy dict_a = { 'A': 'A', 'B': { 'C':'C', 'D':'D', 'E': { 'F':'F', 'G':'G' } }, 'H': ['I','J'], 'L': [{'M': 'M', 'N': 'N'}, {'O':'O'}] } dict_b = { 'A': 'a', 'B': { 'C':'c', 'E': { 'F':'f', } }, 'H': ['k'], 'L': [{'N': 'n'}, {'P':'p'}] } def merge_list(a, b): m = copy.copy(a) for i, value in enumerate(b): if isinstance(value, dict): m[i] = merge_dict(a[i], b[i]) elif isinstance(value, list): m[i] = merge_list(a[i], b[i]) else: m.append(value) return m def merge_dict(a, b): m = copy.copy(a) for item in b: if isinstance(b[item], dict): m[item] = merge_dict(a[item], b[item]) elif isinstance(b[item], list): m[item] = merge_list(a[item], b[item]) else: m[item] = b[item] return m print(merge_dict(dict_a, dict_b)) |
実行結果
{'H': ['I', 'J', 'k'], 'B': {'E': {'F': 'f', 'G': 'G'}, 'D': 'D', 'C': 'c'}, 'A': 'a', 'L': [{'M': 'M', 'N': 'n'}, {'O': 'O', 'P': 'p'}]} |
ほしい結果が得られました。
配列の扱いをどうするか難しいところですね。
辞書をマージする時はお気をつけください。
この記事を書いた人
-
新卒3年目で脱新人を目指してます。
フロントに興味を持ち始めた今日このごろ。
趣味は 麻雀 プログラミング 音楽。
運動不足を感じているため、ダンスを始めようかと思っています。
最近書いた記事
- 2019.06.26コンテナイメージの縮小
- 2019.05.27Chromeのユーザ切り替えで複数のAWS環境の管理をわかりやすくする
- 2019.04.15ECRのライフサイクルポリシー
- 2019.03.29KongでOAuth2の認証手順