Asignación y modificación de variables (en python)

Cuando ejecuté este script (Python v2.6):

a = [1,2] b = a a.append(3) print a >>>> [1,2,3] print b >>>> [1,2,3] 

Esperaba que la print b produjera [1,2] . ¿Por qué b cambió cuando todo lo que hice fue cambiar a? ¿Está b atado permanentemente a un? Si es así, ¿puedo hacerlos independientes? ¿Cómo?

La administración de memoria en Python implica una ubicación de memoria de montón privado que contiene todos los objetos y estructuras de datos de Python.

El tiempo de ejecución de Python solo se ocupa de las referencias a objetos (que todos viven en el montón): lo que va en la stack de Python siempre son referencias a valores que viven en otros lugares.

 >>> a = [1, 2] 

variables de python

 >>> b = a 

variables de python

 >>> a.append(3) 

variables de python

Aquí podemos ver claramente que la variable b está vinculada al mismo objeto que a .

Puede utilizar el operador is para comprobar si dos objetos son físicamente iguales, es decir, si tienen la misma dirección en la memoria. Esto también puede ser probado usando la función id() .

 >>> a is b >>> True >>> id(a) == id(b) >>> True 

Por lo tanto, en este caso, debe solicitar explícitamente una copia . Una vez que haya hecho eso, no habrá más conexión entre los dos objetos de lista distintos.

 >>> b = list(a) >>> a is b >>> False 

variables de python

Los objetos en Python se almacenan por referencia: no está asignando el valor de a a b , sino un puntero al objeto que a está apuntando.

Para emular la asignación por valor, puede hacer una copia así:

 import copy b = copy.copy(a) # now the code works as "expected" 

Tenga en cuenta que esto tiene desventajas de rendimiento.

En el caso de una matriz, hay un método especial que se basa en segmentos:

 b = a[:] # code also works as expected here 

Actualización : además de esto, con algunos objetos puede usar el constructor, esto incluye listas:

 b = list(a) 

Respuesta corta – Punteros.

Cuando escribe b = a , está configurando b para mirar la misma matriz que a. Tienes que hacer una nueva matriz con copias de los elementos para separarlos. En este caso, algo como b = [n for n in a] funcionaría bien. Para operaciones más complejas, puede consultar http://docs.python.org/library/copy.html .

Es posible que desee ver este enlace. El problema que tiene aquí es a y b ambos apuntan a la misma ubicación de memoria, por lo que cambiar uno cambia al otro. En su lugar, quieres hacer algo como esto:

 a = [1,2] b = list(a) 

a es un puntero a la lista [1,2] .

Cuando hace la asignación b = a el valor de b es la dirección de la lista [1,2] .

Entonces, cuando hace un a.append(3) realidad no está cambiando a , está cambiando la lista a la que apunta. Como a y b apuntan a la misma lista, ambos parecen cambiar cuando modifica la otra.

Si simplemente desea copiar el contenido de la lista a a b, en lugar de hacer un puntero ba a:

 b = a[:] 

El uso del operador de división copiará el contenido de la lista en b, de modo que su ejemplo se convierta en:

 a = [1,2] b = a[:] a.append(3) print a >>>> [1,2,3] print b >>>> [1,2]