2015-03-03 4 views
1

Я несколько словарей следующим образом:Объединение нескольких словарей в Python

{"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 является первым ключом во всех словарях, тогда вложенные ключи будет отличаться. Если в словаре есть один и тот же вложенный словарь в двух словарях, ключи должны быть объединены (например: item3 в словах 1 и 2). Как я могу достичь этого?

+0

возможно дубликат [объединения «несколько» питон словарей] (HTTP: // stackoverflow.com/questions/9415785/merging-several-python-dictionaries) –

+2

Почему существует элемент '" item1 ": {" item2 ":" 300 "}' в желаемом выходе? Разве это не должно быть «item2»: «300»? – jwodder

+0

@jwodder - Это было набрано ошибочно .. Отредактировано – NagaLakshmi

ответ

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

Это сработало отлично .. Спасибо – NagaLakshmi

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}}. Приведенный выше код позволяет недиктическому значению перезаписывать предыдущее значение, но он не будет работать, если словарь попытается заменить не-словарь. Вы можете раскомментировать строки проверки ошибок, чтобы любой конфликт вызывал исключение или, возможно, записывал вашу собственную логику обработки ошибок, которая разрешает конфликты.

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) 
Смежные вопросы