目次

目次

Pythonで2つの辞書型(dict型)をマージ

高橋克幸
高橋克幸
最終更新日2018/07/26 投稿日2018/07/26

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年目で脱新人を目指してます。
フロントに興味を持ち始めた今日このごろ。
趣味は 麻雀 プログラミング 音楽。
運動不足を感じているため、ダンスを始めようかと思っています。

目次