302 votes

Mise à jour de la valeur d'un dictionnaire imbriqué de profondeur variable

Je cherche un moyen de mettre à jour le dictionnaire 1 avec le contenu du dictionnaire 2 sans écraser le niveau A.

dictionary1={'level1':{'level2':{'levelA':0,'levelB':1}}}
update={'level1':{'level2':{'levelB':10}}}
dictionary1.update(update)
print dictionary1
{'level1': {'level2': {'levelB': 10}}}

Je sais que la mise à jour supprime les valeurs du niveau 2 car elle met à jour la clé la plus basse du niveau 1.

Comment puis-je résoudre ce problème, étant donné que le dictionnaire 1 et la mise à jour peuvent avoir n'importe quelle longueur ?

0 votes

L'imbrication est-elle toujours de trois niveaux de profondeur ou peut-on avoir une imbrication d'une profondeur arbitraire ?

1 votes

Il peut avoir n'importe quelle profondeur/longueur.

0 votes

Corrigez-moi si je me trompe, mais il semble que la solution idéale ici nécessite la mise en œuvre du modèle de conception composite.

0voto

Yifu Yan Points 1375

Une autre façon d'utiliser la récursion :

def updateDict(dict1,dict2):
    keys1 = list(dict1.keys())
    keys2= list(dict2.keys())
    keys2 = [x for x in keys2 if x in keys1]
    for x in keys2:
        if (x in keys1) & (type(dict1[x]) is dict) & (type(dict2[x]) is dict):
            updateDict(dict1[x],dict2[x])
        else:
            dict1.update({x:dict2[x]})
    return(dict1)

-1voto

user7337353 Points 11

Un nouveau Q comment faire un porte-clés

dictionary1={'level1':{'level2':{'levelA':0,'levelB':1}},'anotherLevel1':{'anotherLevel2':{'anotherLevelA':0,'anotherLevelB':1}}}
update={'anotherLevel1':{'anotherLevel2':1014}}
dictionary1.update(update)
print dictionary1
{'level1':{'level2':{'levelA':0,'levelB':1}},'anotherLevel1':{'anotherLevel2':1014}}

-1voto

Craig N. Points 1

Vous pouvez essayer ceci, il fonctionne avec des listes et est pur :

def update_keys(newd, dic, mapping):
  def upsingle(d,k,v):
    if k in mapping:
      d[mapping[k]] = v
    else:
      d[k] = v
  for ekey, evalue in dic.items():
    upsingle(newd, ekey, evalue)
    if type(evalue) is dict:
      update_keys(newd, evalue, mapping)
    if type(evalue) is list:
      upsingle(newd, ekey, [update_keys({}, i, mapping) for i in evalue])
  return newd

-5voto

Nas Banov Points 7293

C'est un peu à part, mais avez-vous vraiment besoin de dictionnaires imbriqués ? Selon le problème, un dictionnaire plat peut parfois suffire... et avoir l'air bien :

>>> dict1 = {('level1','level2','levelA'): 0}
>>> dict1['level1','level2','levelB'] = 1
>>> update = {('level1','level2','levelB'): 10}
>>> dict1.update(update)
>>> print dict1
{('level1', 'level2', 'levelB'): 10, ('level1', 'level2', 'levelA'): 0}

7 votes

La structure imbriquée provient de jeux de données json entrants, je voudrais donc les garder intacts,...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X