Si vienes a Python desde un lenguaje en C / Java / etc. familia, puede ayudarlo a dejar de pensar en a
una "variable" y comenzar a pensar en ella como un "nombre".
a
, b
y c
no son variables diferentes con valores iguales; son nombres diferentes para el mismo valor idéntico. Las variables tienen tipos, identidades, direcciones y todo tipo de cosas como esa.
Los nombres no tienen nada de eso. Los valores sí, por supuesto, y puede tener muchos nombres para el mismo valor.
Si le das Notorious B.I.G.
un hot dog, * Biggie Smalls
y Chris Wallace
tienes un hot dog. Si cambia el primer elemento de a
a 1, los primeros elementos de b
y c
son 1.
Si desea saber si dos nombres están nombrando el mismo objeto, use el is
operador:
>>> a=b=c=[0,3,5]
>>> a is b
True
Luego preguntas:
¿Qué es diferente de esto?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
Aquí, vuelve a vincular el nombre e
al valor 4
. Eso no afecta los nombres d
y f
de ninguna manera.
En su versión anterior, estaba asignando a a[0]
, no a a
. Entonces, desde el punto de vista de a[0]
, estás volviendo a vincular a[0]
, pero desde el punto de vista de a
, lo estás cambiando en el lugar.
Puede usar la id
función, que le proporciona un número único que representa la identidad de un objeto, para ver exactamente qué objeto es cuál, incluso cuando is
no puede ayudar:
>>> a=b=c=[0,3,5]
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261120
>>> id(b[0])
4297261120
>>> a[0] = 1
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261216
>>> id(b[0])
4297261216
Observe que a[0]
ha cambiado de 4297261120 a 4297261216; ahora es un nombre para un valor diferente. Y b[0]
ahora también es un nombre para ese mismo nuevo valor. Eso es porque a
y b
todavía están nombrando el mismo objeto.
Debajo de las cubiertas, en a[0]=1
realidad está llamando a un método en el objeto de la lista. (Es equivalente a a.__setitem__(0, 1)
). Entonces, en realidad no está volviendo a unir nada. Es como llamar my_object.set_something(1)
. Claro, es probable que el objeto vuelva a vincular un atributo de instancia para implementar este método, pero eso no es lo importante; lo importante es que no estás asignando nada, solo estás mutando el objeto. Y es lo mismo con a[0]=1
.
user570826 preguntó:
¿Qué pasa si tenemos, a = b = c = 10
Esa es exactamente la misma situación que a = b = c = [1, 2, 3]
: tiene tres nombres para el mismo valor.
Pero en este caso, el valor es an int
, y int
s son inmutables. En cualquiera de los casos, se puede volver a enlazar a
a un valor diferente (por ejemplo, a = "Now I'm a string!"
), pero el no va a afectar al valor original, el cual b
, y c
seguirá siendo nombres para. La diferencia es que con una lista, puede cambiar el valor [1, 2, 3]
en [1, 2, 3, 4]
la marcha, por ejemplo, a.append(4)
; ya que es en realidad el cambio del valor que b
y c
son nombres para, b
ahora quieren b [1, 2, 3, 4]
. No hay forma de cambiar el valor 10
en otra cosa. 10
tiene 10 años para siempre, al igual que Claudia el vampiro tiene 5 para siempre (al menos hasta que sea reemplazada por Kirsten Dunst).
* Advertencia: no le dé a Notorious BIG un hot dog. Los zombis del rap gangsta nunca deberían ser alimentados después de la medianoche.
a
,b
yc,
a todos los puntos con el mismo valor (en este caso una lista), o quierea=0
,b=3
yc=5
. En ese caso, quieresa,b,c = [0,3,5]
o simplementea,b,c = 0,3,5
.