简体   繁体   English

在python中合并多个字典

[英]Merging multiple dictionaries in python

I've few dictionaries as follows: 我的字典如下:

{"item1": {"item2": "300"}}
{"item1": {"item3": {"item4": "400"}}}
{"item1": {"item3": {"item6": "16"}}}
{"item1": {"item7": "aaa"}}
{"item1": {"item8": "bbb"}}
{"item1": {"item9": {"item10" : "2.2"}}}
{"item1": {"item9": {"item11" : "xxx"}}}

I want to merge these dictionaries as follows 我想将这些字典合并如下

{
  "item1": {
    "item2": "300",
    "item3": {
      "item4": "400",
      "item6": "16"
     },
    "item7": "aaa",
    "item8": "bbb",
    "item9": {
      "item10": "2.2",
      "item11": "xxx"
     }
  }
}

item1 is the first key in all dictionaries whereas the nested keys will vary. item1是所有词典中的第一个键,而嵌套键将有所不同。 If there is same nested dictionary within a dictionary in two dictionaries the keys has to be merged (eg: item3 in dictionary 1 and 2). 如果两个字典的字典中有相同的嵌套字典,则必须合并键(例如:字典1和2中的item3)。 How can i achieve this? 我怎样才能做到这一点?

dico_list=[{"item1": {"item2": "300"}}, {"item1": {"item3": {"item4": "400"}}}, {"item1": {"item3": {"item6": "16"}}}, {"item1": {"item7": "aaa"}}, {"item1": {"item8": "bbb"}}, {"item1": {"item9": {"item10" : "2.2"}}}, {"item1": {"item9": {"item11" : "xxx"}}}]

def merge(merge_dico,dico_list):
    for dico in dico_list:
        for key,value in dico.items():
            if type(value)==type(dict()):
                merge_dico.setdefault(key,dict())
                merge(merge_dico[key],[value])
            else:
                merge_dico[key]=value
    return merge_dico

print(merge(dict(),dico_list))
#{'item1': {'item7': 'aaa', 'item9': {'item11': 'xxx', 'item10': '2.2'}, 'item8': 'bbb', 'item3': {'item4': '400', 'item6': '16'}, 'item2': '300'}}

I think this is easiest to do with a recursive helper function: 我认为使用递归辅助函数最简单:

def merge_dict_into(target, d):
    for key, value in d:
        if isinstance(value, dict):
            recursive_target = target.setdefault(key, {})
            # if not isintance(recursive_target, dict): raise ValueError
            merge_dict_into(recursive_target, value)
        else:
            # if key in target: raise ValueError
            target[key] = value

def merge_dicts(dicts):
    target = {}
    for d in dicts:
        merge_dict_into(target, d)
    return target

I'm not sure how you want to handle dictionaries that have conflicts. 我不确定您要如何处理有冲突的字典。 For example, merging {"a": 0} with {"a": 1} or {"a": {"b": 2}} . 例如,将{"a": 0}{"a": 1}{"a": {"b": 2}}合并。 The code above allows a non-dict value to overwrite a previous value, but it will fail if a dictionary tries to replace a non-dictionary. 上面的代码允许非字典值覆盖先前的值,但是如果字典试图替换非字典,则它将失败。 You can uncomment the error checking lines to make any conflict raise an exception, or perhaps write your own error handling logic that resolves the conflicts. 您可以取消注释错误检查行以使任何冲突引发异常,或者编写自己的错误处理逻辑来解决冲突。

Similar as the others, using a recursive function, however also checks if duplicate values exists in the tree: 与其他类似,使用递归函数,但是还会检查树中是否存在重复值:

from pprint import pprint

dicts = [{"item1": {"item2": "300"}},
         {"item1": {"item3": {"item4": "400"}}},
         {"item1": {"item3": {"item6": "16"}}},
         {"item1": {"item7": "aaa"}},
         {"item1": {"item8": "bbb"}},
         {"item1": {"item9": {"item10" : "2.2"}}},
         {"item1": {"item9": {"item11" : "xxx"}}},]


def walk_tree(fill_dict, mydict):
    for key, val in mydict.iteritems():
        if isinstance(val, dict):
            if key not in fill_dict.keys():
                fill_dict[key] = {}
            walk_tree(fill_dict[key], val)

        else:
            if key in fill_dict.keys():
                raise(StandardError, 'Duplicate')
            fill_dict[key] = val


dicts_total = {}

for mydict in dicts:
    walk_tree(dicts_total, mydict)


pprint(dicts_total)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM