python generator yield

¿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