【问题标题】:Merge two nested dicts quickly, retain two values with same key in dicts快速合并两个嵌套字典,返回字典中相同键的两个值
【发布时间】:2019-03-01 07:52:10
【问题描述】:

感谢@naivepredictor 的评论,我发现我的问题模棱两可。

我想合并两个 nesteddeep 字典。它类似于How to merge two dictionaries in a single expression?,但不同的是,我想将两个值合并到一个列表中合并。 它类似于Merge two dictionaries and keep the values for duplicate keys in Python,但这里的dict是嵌套的并且很深。如下: 例如:

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

【问题讨论】:

  • 他们是如此相似。但还是有一点区别:我的问题中的 dict 是嵌套的,而且很深。
  • 你问题中的字典不是嵌套的,也不是很深。问题中的每个字典都有一个键和一个值。
  • 很抱歉。这是第二次问同样的问题。第一次,我使用嵌套字典,但许多评论者认为它与另一个问题重复。所以这次我举一个简单的例子。但是你可以看到:我的代码是递归的,所以字典一定是嵌套的,而且很深。

标签: python dictionary


【解决方案1】:
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)

【讨论】:

    【解决方案2】:

    试试这个:

    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]}
    

    【讨论】:

      猜你喜欢
      • 2016-06-20
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 2022-12-12
      相关资源
      最近更新 更多