2012-02-23 11 views
6

no puedo encontrar información concisa sobre lo que está pasando en este programa muy simple:Python manipulación de variables, no entiendo que

print 'case 1' 
# a and b stay different 
a = [1,2,3] 
b = a 
b = [4,5,6] 

print 'a =',a 
print 'b =',b 

print 
print 'case 2' 
# a and b becomes equal 
a = [1,2,3] 
b = a 
b[0] = 4 
b[1] = 5 
b[2] = 6 

print 'a =',a 
print 'b =',b 
print 

print 'case 3' 
# a and b stay different now 
a = [1,2,3] 
b = a[:] 
b[0] = 4 
b[1] = 5 
b[2] = 6 
print 'a =',a 
print 'b =',b 
print 

print 'case 4' 
# now the funny thing 
a=[1,2,[3]] 
b=a[:] 
b[0] = 4 
b[1] = 5 
b[2][0] = 6 # this modifies b and a!!! 

La salida de esta prueba es sencilla:

case 1 
a = [1, 2, 3] 
b = [4, 5, 6] 

case 2 
a = [4, 5, 6] 
b = [4, 5, 6] 

case 3 
a = [1, 2, 3] 
b = [4, 5, 6] 

case 4 
a = [1, 2, [6]] 
b = [4, 5, [6]] 

claramente no entiendo cómo maneja python cada caso. ¿Podría alguien proporcionar un enlace para que pueda leer sobre él, o una breve explicación de lo que está sucediendo?

Muchas gracias.

Respuesta

6

Hay dos cosas importantes aquí:

  • Las variables son sólo etiquetas para señalar objetos
  • lista son mutables en Python y no son números enteros.

Cuando usted encuentra que tanto a y b se modifican, entonces eso es porque ambos apuntan al mismo objeto. Puede hacer id(a) y id(b) para confirmar esto.

En cuanto a los ejemplos, tenga en cuenta que a[:] creará un nuevo objeto que es una copia de a. Sin embargo, será una copia superficial, no una copia profunda. Esto explica por qué en el ejemplo 4, aún puede modificar ambos a y b. Están apuntando a diferentes objetos de lista, pero un elemento es otra lista que comparten ambos.

4

Caso 1: El nombre b es de rebote.

Caso 2: a y b están obligados al mismo objeto.

Caso 3: Una copia superficial de a está limitada a b. Las listas son diferentes, pero los objetos dentro de la lista son los mismos.

Caso 4: Una copia superficial de a está vinculada a b, y luego uno de los objetos está mutado.

El volver a enlazar no muta y la mutación no vuelve a enlazarse.

3
print 'case 1' 
# a and b stay different 
a = [1,2,3] 
b = a    #At this point 'b' and 'a' are the same, 
        #just names given to the list 
b = [4,5,6]  #At this point you assign the name 'b' to a different list 

print 'a =',a 
print 'b =',b 

print 
print 'case 2' 
# a and b becomes equal 
a = [1,2,3]  #At this point 'b' and 'a' are the same, 
        #just names given to the list 
b = a 
b[0] = 4   #From here you modify the list, since both 'a' and 'b' 
        #reference the same list, you will see the change in 'a' 
b[1] = 5 
b[2] = 6 


print 'case 3' 
# a and b stay different now 
a = [1,2,3] 
b = a[:]    #At this point you COPY the elements from 'a' into a new 
         #list that is referenced by 'b' 
b[0] = 4    #From here you modify 'b' but this has no connection to 'a' 
b[1] = 5 
b[2] = 6 
print 'a =',a 
print 'b =',b 
print 

print 'case 4' 
# now the funny thing 
a=[1,2,[3]] 
b=a[:]   #At this point you COPY the elements from 'a' into a new 
       #list that is referenced by 'b' 
b[0] = 4  #Same as before 
b[1] = 5 
b[2][0] = 6 # this modifies b and a!!! #Here what happens is that 'b[2]' holds 
       #the same list as 'a[2]'. Since you only modify the element of that 
       #list that will be visible in 'a', try to see it as cases 1/2 just 
       #'recursively'. If you do b[2] = 0, that won't change 'a' 
+0

Explicación destacada. Esto me ayudó enormemente, especialmente la declaración de la lista [:]. Gracias. – trinkner