在python中合并多个词典

时间:2015-03-03 17:38:46

标签: python dictionary

我的字典很少如下:

{"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"}}}

我想合并这些词典如下

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

item1是所有词典中的第一个键,而嵌套键会有所不同。如果两个词典中的字典中存在相同的嵌套字典,则必须合并键(例如:字典1和2中的item3)。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我认为使用递归辅助函数最简单:

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

我不确定你想如何处理有冲突的字典。例如,将{"a": 0}{"a": 1}{"a": {"b": 2}}合并。上面的代码允许非dict值覆盖先前的值,但如果字典试图替换非字典,它将失败。您可以取消注释错误检查行以使任何冲突引发异常,或者编写您自己的错误处理逻辑来解决冲突。

答案 2 :(得分:0)

与其他类似,使用递归函数,但也会检查树中是否存在重复值:

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)