79 votes

Par défaut multiniveau avec profondeur variable ?

J'ai une grande liste comme :

[A][B1][C1]=1
[A][B1][C2]=2
[A][B2]=3
[D][E][F][G]=4

Je veux construire une dictée à plusieurs niveaux comme :

A
--B1
-----C1=1
-----C2=1
--B2=3
D
--E
----F
------G=4

Je sais que si j'utilise un jugement par défaut récursif, je peux écrire table[A][B1][C1]=1 table[A][B2]=2, mais cela ne fonctionne que si j'insère ces instructions.

Lors de l'analyse de la liste, je n'ai pas besoin de combien de [] avant d'appeler table[key1][key2][...].

197voto

Hugo Walter Points 502

Vous pouvez le faire sans même définir une classe :

from collections import defaultdict

nested_dict = lambda: defaultdict(nested_dict)
nest = nested_dict()

nest[0][1][2][3][4][5] = 6

18voto

Apalala Points 2999

Votre exemple dit qu'à n'importe quel niveau, il peut y avoir une valeur, et aussi un dictionnaire de sous-éléments. Cela s'appelle un arbre, et il y a beaucoup d'implémentations disponibles pour eux. Ceci est un :

from collections import defaultdict
class Tree(defaultdict):
    def __init__(self, value=None):
        super(Tree, self).__init__(Tree)
        self.value = value

root = Tree()
root.value = 1
root['a']['b'].value = 3
print root.value
print root['a']['b'].value
print root['c']['d']['f'].value

Sorties :

1
3
None

Vous pouvez faire quelque chose de similaire en écrivant l'entrée dans JSON et en utilisant json.load pour la lire comme une structure de dictionnaires imbriqués.

12voto

Bouke Versteegh Points 199

Je pense que la mise en œuvre la plus simple d'un dictionnaire récursif est celle-ci. Seuls les nœuds feuilles peuvent contenir des valeurs.

# Define recursive dictionary
from collections import defaultdict
tree = lambda: defaultdict(tree)

Utilisation :

# Create instance
mydict = tree()

mydict['a'] = 1
mydict['b']['a'] = 2
mydict['c']
mydict['d']['a']['b'] = 0

# Print
import prettyprint
prettyprint.pp(mydict)

Sortie :

{
  "a": 1, 
  "b": {
    "a": 1
  }, 
  "c": {},
  "d": {
    "a": {
      "b": 0
    }
  }
}

6voto

gabe Points 807

Ceci est équivalent à ce qui précède, mais en évitant la notation lambda. Peut-être plus facile à lire ?

def dict_factory():
   return defaultdict(dict_factory)

your_dict = dict_factory()

Aussi -- à partir des commentaires -- si vous souhaitez mettre à jour à partir d'une dictée existante, vous pouvez simplement appeler

your_dict[0][1][2].update({"some_key":"some_value"})

Pour ajouter des valeurs à la dictée.

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