快速合并两个嵌套的字典,在字典中使用相同的键保留两个值

时间:2019-03-01 07:52:10

标签: python dictionary

由于@naivepredictor的评论,我发现我的问题是模棱两可的。

我想合并两个嵌套 deep 字典。它与How to merge two dictionaries in a single expression?类似,但与之不同,我想将两个值合并为一个合并时列出。 它类似于Merge two dictionaries and keep the values for duplicate keys in Python,但此处的字典是嵌套且深的。如下: 例如:

dic_a = {
    'a1': {'a2': {'a3': 4}},
    'a11': {'a2': {'a3': 4}},
    'a111': {'a2': {'a3': 4}},
    'a1111': {'a2': {'a3': 4}}
}
dic_b = {
    'a1': {'a2': {'a3': [4, 9]}},
    'b1': {'b2': {'b3': 99}},
    'b11': {'b2': {'b3': 99}},
    'b111': {'b2': {'b3': 99}},
    'b1111': {'b2': {'b3': 99}}
}

print(merged_dict)
"""
{'a1': {'a2': {'a3': [4, 4, 9]}},
 'a11': {'a2': {'a3': 4}},
 'a111': {'a2': {'a3': 4}},
 'a1111': {'a2': {'a3': 4}},
 'b1': {'b2': {'b3': 99}},
 'b11': {'b2': {'b3': 99}},
 'b111': {'b2': {'b3': 99}},
 'b1111': {'b2': {'b3': 99}}}
"""

我已经实现了merge_dicts递归。如下。

from copy import deepcopy


def _add_value_to_list(value, lis):
    if value:
        if isinstance(value, list):
            lis.extend(value)
        else:
            lis.append(value)
    else:
        pass


def _merge_value(value_a, value_b):
    merged_value = []
    _add_value_to_list(value_a, merged_value)
    _add_value_to_list(value_b, merged_value)
    return merged_value


def _recursion_merge_dict(new_dic, dic_a, dic_b):
    if not dic_a or not dic_b:
        return new_dic
    else:
        if isinstance(new_dic, dict):
            for k, v in new_dic.items():
                new_dic[k] = _recursion_merge_dict(v, dic_a.get(k, {}), dic_b.get(k, {}))
            return new_dic
        else:
            return _merge_value(dic_a, dic_b)


def merge_dicts(dic_a, dic_b):
    new_dic = deepcopy(dic_a)
    new_dic.update(dic_b)

    return _recursion_merge_dict(new_dic, dic_a, dic_b)

但是它运行缓慢,我需要一个更快的。谢谢。

需要合并的字典的叶子值仅属于listunicode

2 个答案:

答案 0 :(得分:0)

尝试一下:

dic_a = { 'a1': '4'}
dic_b = { 'a1': '9'}
def merge_dicts(dict_a, dict_b):
    return { k : list(filter(lambda x: x is not None, [dic_a[k] if (k in dic_a) else None]+[dic_b[k] if (k in dic_b) else None])) for k in set(list(dic_a.keys()) + list(dic_b.keys()))}
merge_dicts(dic_a, dic_b)    # {'a1': ['4', '9']}

也适用于具有多个键的字典:

dic_a = {'a1': '19', 'b1': 564, 'c1': 5641}
dic_b = {'a1': '9', 'b1': 4, 'c1': 5, 'd1' : 0}
merge_dicts(dic_a, dic_b)    # {'b1': [564, 4], 'c1': [5641, 5], 'a1': ['19', '9'], 'd1': [0]}

答案 1 :(得分:0)

def merger(dic_a, dic_b):
    dic_merged = {}
    for i in dic_a:
        if i in dic_b:
            dic_merged[i] = [dic_a[i]] + [dic_b[i]]
        else:
            dic_merged[i] = dic_a[i]
    for i in dic_b:
        if i not in dic_a:
            dic_merged[i] = dic_b[i]
    return (dic_merged)
merger(dic_a, dic_b)