¿Hay alguna manera de hacer que un defaultdict también sea el predeterminado para el defaultdict? (es decir, ¿defaultdict recursivo de nivel infinito?)
Quiero poder hacer:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Entonces, puedo hacerlo x = defaultdict(defaultdict), pero eso es solo un segundo nivel:
x[0]
{}
x[0][0]
KeyError: 0
Hay recetas que pueden hacer esto. Pero, ¿puede hacerse simplemente usando los argumentos normales de defaultdict?
Tenga en cuenta que esto es preguntar cómo hacer un defaultdict recursivo de nivel infinito, por lo que es distinto a Python: defaultdict de defaultdict? , que era cómo hacer un defaultdict de dos niveles.
Probablemente termine usando el patrón de grupo , pero cuando me di cuenta de que no sabía cómo hacer esto, me interesó.
python
recursion
defaultdict
Corley Brigman
fuente
fuente

Respuestas:
Para un número arbitrario de niveles:
Por supuesto, también puedes hacer esto con una lambda, pero creo que las lambdas son menos legibles. En cualquier caso, se vería así:
fuente
lambdano funcionará.Las otras respuestas aquí le dicen cómo crear un
defaultdictque contiene "infinitamente muchos"defaultdict, pero no abordan lo que creo que pudo haber sido su necesidad inicial, que era simplemente tener un defecto predeterminado de dos profundidades.Es posible que haya estado buscando:
Las razones por las que podría preferir esta construcción son:
defaultdictsea algo más que un diccionario, por ejemplo ,:defaultdict(lambda: defaultdict(list))odefaultdict(lambda: defaultdict(set))fuente
lambdaformulario es correcto, porquedefaultdict(something)devuelve un objeto similar a un diccionario, ¡perodefaultdictespera un invocable! ¡Gracias!dict(result)antes del encurtidoHay un ingenioso truco para hacer eso:
Entonces puedes crear tu
xconx = tree().fuente
Similar a la solución de BrenBarn, pero no contiene el nombre de la variable
treedos veces, por lo que funciona incluso después de los cambios en el diccionario de variables:Entonces puedes crear cada nuevo
xconx = tree().Para la
defversión, podemos usar el alcance de cierre de funciones para proteger la estructura de datos de la falla donde las instancias existentes dejan de funcionar si eltreenombre se recupera. Se parece a esto:fuente
También propondría más implementación de estilo OOP, que admite el anidamiento infinito y el formato correcto
repr.Uso:
fuente
*argsy**kwargsque le permite funcionar como eldefaultdict, es decir, crear un dict con argumentos de palabras clave. Esto es útil para pasarNestedDefaultDictenjson.loadAquí hay una función recursiva para convertir un dict por defecto recursivo en un dict normal
fuente
Basé esto de la respuesta de Andrew aquí. Si está buscando cargar datos de un json o un dict existente en el nesdict defaultdict, vea este ejemplo:
https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775
fuente