defaultdict anidado de defaultdict
¿Hay alguna manera de hacer que un defaultdict también sea el predeterminado para defaultdict? (es decir, ¿dictado por defecto 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, ¿se puede hacer simplemente usando los argumentos normales de defaultdict?
Tenga en cuenta que esto pregunta cómo hacer un defaultdict recursivo de nivel infinito, por lo que es distinto de Python: defaultdict of 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é.
Las otras respuestas aquí le dicen cómo crear un defaultdict
que contenga "infinitos" defaultdict
, pero no abordan lo que creo que pudo haber sido su necesidad inicial, que era simplemente tener un defaultdict de dos profundidades.
Es posible que haya estado buscando:
defaultdict(lambda: defaultdict(dict))
Las razones por las que podría preferir esta construcción son:
- Es más explícita que la solución recursiva y, por tanto, probablemente más comprensible para el lector.
- Esto permite que la "hoja" del
defaultdict
sea algo más que un diccionario, por ejemplo:defaultdict(lambda: defaultdict(list))
odefaultdict(lambda: defaultdict(set))
Para un número arbitrario de niveles:
def rec_dd():
return defaultdict(rec_dd)
>>> x = rec_dd()
>>> x['a']['b']['c']['d']
defaultdict(<function rec_dd at 0x7f0dcef81500>, {})
>>> print json.dumps(x)
{"a": {"b": {"c": {"d": {}}}}}
Por supuesto, también puedes hacer esto con una lambda, pero creo que las lambdas son menos legibles. En cualquier caso quedaría así:
rec_dd = lambda: defaultdict(rec_dd)