not - Python defaultdict y lambda
name ''defaultdict'' is not defined (5)
Creo que la primera línea significa que cuando llamo
x[k]
para una clave inexistentek
(como una declaración comov=x[k]
), el par clave-valor(k,0)
se agregará automáticamente al diccionario , como si la declaraciónx[k]=0
se ejecutara primero.
Está bien. Esto es más idiomáticamente escrito
x = defaultdict(int)
En el caso de y
, cuando haces y["ham"]["spam"]
, la clave "ham"
se inserta en y
si no existe. El valor asociado con este se convierte en un defaultdict
en el que "spam"
se inserta automáticamente con un valor de 0
.
Es decir, es una clase de incumplimiento de "dos niveles". Si "ham" not in y
, entonces evaluar y["ham"]["spam"]
es como hacer
y["ham"] = {}
y["ham"]["spam"] = 0
en términos de dict
ordinario.
En el código de otra persona leo las siguientes dos líneas:
x = defaultdict(lambda: 0)
y = defaultdict(lambda: defaultdict(lambda: 0))
Como el argumento de defaultdict es una fábrica predeterminada, creo que la primera línea significa que cuando invoco x [k] para una clave inexistente k (como una declaración como v = x [k]), el par clave-valor (k , 0) se agregará automáticamente al diccionario, como si la instrucción x [k] = 0 se ejecutara primero. ¿Estoy en lo correcto?
¿Y qué hay de y? Parece que la fábrica predeterminada creará un valor predeterminado con 0. Por defecto, ¿qué significa eso en concreto? Traté de jugar con él en el shell de Python, pero no pude entender qué es exactamente.
Estás en lo correcto por lo que hace el primero. En cuanto a y
, creará un valor por defecto con 0 predeterminado cuando una clave no existe en y
, por lo que puede pensar en esto como un diccionario anidado. Considere el siguiente ejemplo:
y = defaultdict(lambda: defaultdict(lambda: 0))
print y[''k1''][''k2''] # 0
print dict(y[''k1'']) # {''k2'': 0}
Para crear una estructura de diccionario anidada equivalente sin un default, necesitarías crear un dict interno para y[''k1'']
y luego establecer y[''k1''][''k2'']
en 0, pero el defaultdict hace todo esto detrás de las escenas cuando encuentra llaves que no ha visto:
y = {}
y[''k1''] = {}
y[''k1''][''k2''] = 0
La siguiente función puede ayudar a jugar con esto en un intérprete para mejorar su comprensión:
def to_dict(d):
if isinstance(d, defaultdict):
return dict((k, to_dict(v)) for k, v in d.items())
return d
Esto devolverá el equivalente dict de un incumplimiento predeterminado anidado, que es mucho más fácil de leer, por ejemplo:
>>> y = defaultdict(lambda: defaultdict(lambda: 0))
>>> y[''a''][''b''] = 5
>>> y
defaultdict(<function <lambda> at 0xb7ea93e4>, {''a'': defaultdict(<function <lambda> at 0xb7ea9374>, {''b'': 5})})
>>> to_dict(y)
{''a'': {''b'': 5}}
Todas las respuestas son lo suficientemente buenas, pero estoy dando la respuesta para agregar más información:
"defaultdict requiere un argumento que sea invocable. Ese resultado de devolución de ese objeto invocable es el valor predeterminado que devuelve el diccionario cuando intenta acceder al diccionario con una clave que no existe".
Aquí hay un ejemplo
SAMPLE= {''Age'':28, ''Salary'':2000}
SAMPLE = defaultdict(lambda:0,SAMPLE)
>>> SAMPLE
defaultdict(<function <lambda> at 0x0000000002BF7C88>, {''Salary'': 2000, ''Age'': 28})
>>> SAMPLE[''Age'']----> This will return 28
>>> SAMPLE[''Phone'']----> This will return 0 # you got 0 as output for a non existing key inside SAMPLE
defaultdict
toma un argumento cero invocable para su constructor, que se invoca cuando no se encuentra la clave, como explicó correctamente.
lambda: 0
siempre devolverá cero, pero el método preferido para hacerlo es defaultdict(int)
, que hará lo mismo.
En cuanto a la segunda parte, el autor desea crear un nuevo defaultdict(int)
o un diccionario anidado, siempre que no se encuentre una clave en el diccionario de nivel superior.
y = defaultdict(lambda:defaultdict(lambda:0))
será útil si prueba esto y[''a''][''b''] += 1