2017-10-13 2 views
4

Je cherche à fusionner deux dictionnaires montrés ci-dessous, mais je n'ai pas réussi à le faire.Fusion de deux dictionnaires Python dans un dictionnaire ayant la même clé

J'ai lu beaucoup de billets de blog, mais je n'ai pas trouvé de réponse.

dict1={"KPNS": {"metadocdep": {"eta": {"sal": "2"}}, "metadocdisp": {"meta": {"head": "1"}}}, "EGLS": {"apns": {"eta": {"sal": "2"}}, "gcm": {"meta": {"head": "1"}}}} 

dict2={"KPNS": {"metadocdep": {"eta": {"sal": "7"}}, "metadocdisp": {"meta": {"head": "5"}}}, "EGLS": {"apns": {"eta": {"sal": "7"}}, "gcm": {"meta": {"head": "9"}}}} 
finaldict = {key:(dict1[key], dict2[key]) for key in dict1} 

print finaldict 

Ma sortie finale devrait être comme:

{"KPNS": {"metadocdep": {"eta": {"sal": [2,7]}}, 
      "metadocdisp": {"meta": {"head": [1,5]}}}, 
"EGLS": {"apns": {"eta": {"sal": [2,7]}}, 
      "gcm": {"meta": {"head": [1,9]}}}} 

Comment puis-je faire cela?

+0

-ce que vos dicts ont une profondeur constante ou ils ont subdicts inderminate? – lotrus28

+0

parce que vous devez définir une structure pour ur dict. y a-t-il plus de 4 niveaux? seul le dernier niveau doit être une liste? pouvons-nous avoir un élément différent dans les deux dict dans chaque niveau? –

+0

ils ont une profondeur constante –

Répondre

3

Avec defaultdict

Si vous savez ce que la profondeur prévue est, vous pouvez utiliser defaultdicts imbriqué pour définir final_dict:

from collections import defaultdict 

final_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 

final_dict['a']['b']['c'].append(1) 
print(final_dict) 
# defaultdict(<function <lambda> at 0x7f2ae7f41e18>, {'a': defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f2ae636b730>, {'b': defaultdict(<class 'list'>, {'c': [1]})})}) 

Il y a beaucoup de la production supplémentaire en raison de la defaultdict, mais vous pouvez traiter final_dict comme un dict simple.

Avec dicts

Avec dicts standard, vous devrez utiliser setdefault. Le code ne devient pas très lisible, mais:

dict1 = {"KPNS": {"metadocdep": {"eta": {"sal": "2"}}, "metadocdisp": {"meta": { 
    "head": "1"}}}, "EGLS": {"apns": {"eta": {"sal": "2"}}, "gcm": {"meta": {"head": "1"}}}} 

dict2 = {"KPNS": {"metadocdep": {"eta": {"sal": "7"}}, "metadocdisp": {"meta": { 
    "head": "5"}}}, "EGLS": {"apns": {"eta": {"sal": "7"}}, "gcm": {"meta": {"head": "9"}}}} 

final_dict = {} 
for d in [dict1, dict2]: 
    for level1 in d: 
     for level2 in d[level1]: 
      for level3 in d[level1][level2]: 
       for level4 in d[level1][level2][level3]: 
        final_dict.setdefault(level1, {}).setdefault(level2, {}).setdefault(
         level3, {}).setdefault(level4, []).append(d[level1][level2][level3][level4]) 

print(final_dict) 
# {'KPNS': {'metadocdep': {'eta': {'sal': ['2', '7']}}, 'metadocdisp': {'meta': {'head': ['1', '5']}}}, 'EGLS': {'apns': {'eta': {'sal': ['2', '7']}}, 'gcm': {'meta': {'head': ['1', '9']}}}} 

Il est peut-être un peu plus efficace avec dict.items():

for d in [dict1, dict2]: 
    for level1, d2s in d.items(): 
     for level2, d3s in d2s.items(): 
      for level3, d4s in d3s.items(): 
       for level4, v in d4s.items(): 
        final_dict.setdefault(level1, {}).setdefault(level2, {}).setdefault(
         level3, {}).setdefault(level4, []).append(v)