¿Por qué este generador de Python está devolviendo el mismo valor cada vez?

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