¿Por qué este generador de Python devuelve el mismo valor cada vez?
generator yield (2)
Tengo este generador que produce listas:
def gen():
state = [None]
for i in range(5):
state[0] = i
yield state
Y aquí está el resultado, cuando lo llamo:
>>> list(gen())
[[4], [4], [4], [4], [4]]
¿Por qué son todos los elementos
[4]
?
¿No debería ser
[[0], [1], [2], [3], [4]]
?
Está
yielding
la misma
list/object
para que siempre vea los últimos valores agregados a la lista.
Debe entregar una copia:
yield state.copy()
O cree la lista dentro del primer bucle:
for i in range(5):
state = [i]
Sería tan fácil crear una nueva lista / objeto cada vez:
def gen():
for i in range(5):
state = [None]
state[0] = i
yield state
Estás reutilizando el mismo objeto de lista. Su generador devuelve un objeto una y otra vez, manipulándolo a medida que avanza, pero cualquier otra referencia a él ve esos mismos cambios:
>>> r = list(gen())
>>> r
[[4], [4], [4], [4], [4]]
>>> r[0] is r[1]
True
>>> r[0][0] = 42
>>> r
[[42], [42], [42], [42], [42]]
Obtenga una copia de la lista o cree un nuevo objeto de lista nueva en lugar de manipular uno.
def gen_copy():
state = [None]
for i in range(5):
state[0] = i
yield state.copy() # <- copy
def gen_new():
for i in range(5):
state = [i] # <- new list object every iteration
yield state