es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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.

Tags:  , ,

Answer

  1. Avatar for 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 lista lines, lines[-1] se convierte en una referencia a l1. 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 para l1, y ya no se refiere a la lista original. Sin embargo, lines[-1] todavía se refiere a la lista original, por lo que lines[-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 usar l1 = (s1, s2) en lugar de l1 = [s1, s2]. De esta manera, se creará un nuevo objeto de tupla para cada iteración y no habrá problemas con objetos mutables.

    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 = tuple(map(int, i[0].split(",")))
        s2 = tuple(map(int, 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")
    

Comments are closed.