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. 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). 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}}
. 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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.