Existe-t-il un moyen de faire d'un defaultdict également la valeur par défaut pour le defaultdict? (ie defaultdict récursif de niveau infini?)
Je veux pouvoir faire:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Donc, je peux le faire x = defaultdict(defaultdict)
, mais ce n'est qu'un deuxième niveau:
x[0]
{}
x[0][0]
KeyError: 0
Il existe des recettes qui peuvent le faire. Mais cela peut-il être fait simplement en utilisant les arguments normaux defaultdict?
Notez que cela demande comment faire un defaultdict récursif de niveau infini, donc il est distinct de Python: defaultdict de defaultdict? , qui était comment faire un defaultdict à deux niveaux.
Je finirai probablement par utiliser le modèle de groupe , mais quand j'ai réalisé que je ne savais pas comment faire cela, cela m'a intéressé.
python
recursion
defaultdict
Corley Brigman
la source
la source
Réponses:
Pour un nombre arbitraire de niveaux:
Bien sûr, vous pouvez également le faire avec un lambda, mais je trouve que les lambdas sont moins lisibles. Dans tous les cas, cela ressemblerait à ceci:
la source
lambda
ne fonctionnera pas.Les autres réponses ici vous indiquent comment créer un "
defaultdict
qui contient" une infinité "defaultdict
, mais elles ne parviennent pas à répondre à ce que je pense avoir été votre besoin initial qui était simplement d'avoir un defaultdict à deux profondeurs.Vous cherchiez peut-être:
Les raisons pour lesquelles vous pourriez préférer cette construction sont:
defaultdict
être autre chose qu'un dictionnaire, par exemple:defaultdict(lambda: defaultdict(list))
oudefaultdict(lambda: defaultdict(set))
la source
lambda
forme est correcte - parce que ledefaultdict(something)
retourne un objet de type dictionnaire, maisdefaultdict
attend un appelable! Je vous remercie!dict(result)
Il y a une astuce astucieuse pour faire cela:
Ensuite, vous pouvez créer votre
x
avecx = tree()
.la source
Similaire à la solution de BrenBarn, mais ne contient pas le nom de la variable
tree
deux fois, donc cela fonctionne même après des modifications du dictionnaire de variables:Ensuite, vous pouvez créer chaque nouveau
x
avecx = tree()
.Pour la
def
version, nous pouvons utiliser la portée de fermeture de fonction pour protéger la structure de données de la faille où les instances existantes cessent de fonctionner si letree
nom est rebondi. Cela ressemble à ceci:la source
Je proposerais également une implémentation plus de style POO, qui prend en charge l'imbrication infinie ainsi que correctement formatée
repr
.Usage:
la source
*args
et**kwargs
qui lui permet de fonctionner comme ledefaultdict
, à savoir de créer un dict avec des arguments de mots clés. Ceci est utile pour passerNestedDefaultDict
enjson.load
voici une fonction récursive pour convertir un dict par défaut récursif en un dict normal
la source
J'ai basé ceci de la réponse d'Andrew ici. Si vous cherchez à charger des données à partir d'un json ou d'un dict existant dans le defaultdict de nester, consultez cet exemple:
https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775
la source