Tengo este generador que produce listas:
def gen(): state = [None] for i in range(5): state[0] = i yield state
Y aquí está la salida, cuando la 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á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]]
Cree 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
Está yielding
la misma list/object
por lo que siempre ve los últimos valores agregados a la lista. Debes entregar una copia:
yield state.copy()
O crea 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