Cambiar uno de dos objetos que son iguales en memoria no cambia el otro objeto.
Simplemente, tengo dos listas que son el mismo objeto, como
lines.append(l1)
lines[-1] is l1
>> True
Esto evalúa a True, por lo que deberían ser el mismo punto en memoria. Pero cuando hago
l1=[]
lines[-1]==l1
>> False
No entiendo cómo dos objetos podrían apuntar al mismo punto en memoria, ya que lines[-1] is l1
evalúa a verdadero, pero luego cambiar l1 no cambia lines[-1].
El código real que estaba usando y que causó esto es
number=['0,9 -> 5,9', '8,0 -> 0,8', '9,4 -> 3,4', '2,2 -> 2,1', '7,0 -> 7,4', '6,4 -> 2,0', '0,9 -> 2,9', '3,4 -> 1,4', '0,0 -> 8,8', '5,5 -> 8,2']
lines=[]
for i in number:
i=i.split("->")
i[0]=i[0][:-1]
i[1]=i[1][1:]
s1 = i[0].split(",")
s2 = i[1].split(",")
l1 =[s1,s2]
lines.append(l1)
print(l1==lines[-1],l1 is lines[-1]) #evalúa a True True
l1=[]
print(l1==lines[-1],l1 is lines[-1]) #evalúa a False False
print(l1,lines[-1],"\n")
“`
¿Cómo podría ser l1 lines[-1], pero cambiar l1 no cambia lines[-1]?
Creo que el problema radica en asignarle a l1 un nuevo valor. Si solo hiciera l1.append(1)
, entonces el código funciona como se espera. Sin embargo, al hacer l1 = [32,32]
u otra asignación arbitraria, entonces el código no funciona como se espera.
davy.ai
El problema en el código está relacionado con objetos mutables e inmutables en Python. Cuando se añade una lista a otra lista, la nueva lista se convierte en una referencia a la lista original, y cualquier cambio realizado en la lista original se reflejará en la nueva lista.
En el código proporcionado, cuando
l1
se añade a la listalines
,lines[-1]
se convierte en una referencia al1
. Por lo tanto,l1 is lines[-1]
se evalúa como verdadero porque ambas variables se refieren al mismo objeto en la memoria.Pero cuando
l1
se reasigna a una lista vacía (l1=[]
), se crea un nuevo objeto en la memoria paral1
, y ya no se refiere a la lista original. Sin embargo,lines[-1]
todavía se refiere a la lista original, por lo quelines[-1] == l1
se evalúa como falso.Para evitar esta confusión, se podría utilizar el empaquetado y desempaquetado de tuplas al añadir los valores a la lista
lines
. Por ejemplo, podemos usarl1 = (s1, s2)
en lugar del1 = [s1, s2]
. De esta manera, se creará un nuevo objeto de tupla para cada iteración y no habrá problemas con objetos mutables.