¿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
lambda
no funcionará.Las otras respuestas aquí le dicen cómo crear un
defaultdict
que 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:
defaultdict
sea algo más que un diccionario, por ejemplo ,:defaultdict(lambda: defaultdict(list))
odefaultdict(lambda: defaultdict(set))
fuente
lambda
formulario es correcto, porquedefaultdict(something)
devuelve un objeto similar a un diccionario, ¡perodefaultdict
espera un invocable! ¡Gracias!dict(result)
antes del encurtidoHay un ingenioso truco para hacer eso:
Entonces puedes crear tu
x
conx = tree()
.fuente
Similar a la solución de BrenBarn, pero no contiene el nombre de la variable
tree
dos veces, por lo que funciona incluso después de los cambios en el diccionario de variables:Entonces puedes crear cada nuevo
x
conx = tree()
.Para la
def
versió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 eltree
nombre 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
*args
y**kwargs
que le permite funcionar como eldefaultdict
, es decir, crear un dict con argumentos de palabras clave. Esto es útil para pasarNestedDefaultDict
enjson.load
Aquí 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