Diferentes comportamientos de una lista de Python en una función recursiva.
Estoy aprendiendo a escribir funciones recursivas en Python y encuentro que una lista puede tener diferentes comportamientos dependiendo de si elijo usar res.append(new_loc)
o res + [new_loc]
.
Por ejemplo,
def solver(counter,res):
print("Entrando al solver:", res)
if len(res) >= 4:
return
counter += 1
res.append(counter)
solver(counter,res)
print("solver interno devuelto:", res)
counter += 1
res.append('haha%i'% counter)
solver(0,[])
Esto me da la siguiente salida:
Entrando al solver: []
Entrando al solver: [1]
Entrando al solver: [1, 2]
Entrando al solver: [1, 2, 3]
Entrando al solver: [1, 2, 3, 4]
solver interno devuelto: [1, 2, 3, 4]
solver interno devuelto: [1, 2, 3, 4, 'haha5']
solver interno devuelto: [1, 2, 3, 4, 'haha5', 'haha4']
solver interno devuelto: [1, 2, 3, 4, 'haha5', 'haha4', 'haha3']
La lista res
actúa como un registro y guarda todos los valores.
Sin embargo, si cambio un poco la función solver
:
def solver(counter,res):
print("Acabo de entrar al solver:", res)
if len(res) >= 4:
return
counter += 1
solver(counter,res+[counter])
print("solver interno devuelto:", res)
counter += 1
res.append('haha%i'% counter)
solver(0,[])
La salida se convierte en:
Acabo de entrar al solver: []
Acabo de entrar al solver: [1]
Acabo de entrar al solver: [1, 2]
Acabo de entrar al solver: [1, 2, 3]
Acabo de entrar al solver: [1, 2, 3, 4]
solver interno devuelto: [1, 2, 3]
solver interno devuelto: [1, 2]
solver interno devuelto: [1]
solver interno devuelto: []
En este caso, ¿por qué res.append('haha%i'% counter)
no está funcionando?
davy.ai
En la segunda versión de la función
solver
, donde se utilizares+[counter]
en lugar deres.append(counter)
, se crea una nueva lista que se pasa a la llamada recursiva en lugar de modificar la lista de entradares
. Por lo tanto, cuando se ejecuta la líneares.append('haha%i' % counter)
, se está modificando la lista originalres
que se pasó como entrada a la función, y no la lista que se modificó en la llamada recursiva. Como resultado, la listares
en la salida final no tiene el valor agregado.En resumen, utilizar
res.append
modifica la lista original y es útil cuando queremos realizar un seguimiento de los cambios en la lista a lo largo de las llamadas recursivas. Utilizarres + [new_loc]
crea una nueva lista y es útil cuando queremos evitar modificar la lista original y en su lugar crear una nueva lista con las actualizaciones.