Python asignando múltiples variables al mismo valor? comportamiento de lista

Intenté usar la asignación múltiple como se muestra a continuación para inicializar las variables, pero el comportamiento me confundió, espero reasignar la lista de valores por separado, quiero decir que b [0] yc [0] son ​​igual a 0 que antes.

a=b=c=[0,3,5] a[0]=1 print(a) print(b) print(c) 

El resultado es: [1, 3, 5] [1, 3, 5] [1, 3, 5]

¿Es eso correcto? ¿Qué debo usar para la asignación múltiple? ¿Qué es diferente de esto?

 d=e=f=3 e=4 print('f:',f) print('e:',e) 

resultado: (‘f:’, 3) (‘e:’, 4)

Related of "Python asignando múltiples variables al mismo valor? comportamiento de lista"

Si viene a Python desde un idioma en C / Java / etc. familia, puede ayudarlo a dejar de pensar en a “variable” y empezar a pensar en ella como un “nombre”.

a , b , 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 por el estilo.

Los nombres no tienen nada de eso. Los valores sí, por supuesto, y puedes tener muchos nombres por el mismo valor.

Si le das un perro caliente a Notorious BIG , * Biggie Smalls y Chris Wallace tienen un perro caliente. 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 operador is :

 >>> a=b=c=[0,3,5] >>> a is b True 

Entonces usted pregunta:

¿Qué es diferente de esto?

 d=e=f=3 e=4 print('f:',f) print('e:',e) 

Aquí, estás reencuadrando el nombre e con el valor 4 . Eso no afecta a 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[0] encuadrar a[0] , pero desde el punto de vista de a , lo estás cambiando en el lugar.

Puedes usar la función de id , que te da un número único que representa la identidad de un objeto, para ver exactamente qué objeto es y cuándo 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 siguen nombrando el mismo objeto.


Bajo las cubiertas, a[0]=1 está llamando a un método en el objeto de la lista. (Es equivalente a a.__setitem__(0, 1) .) Por lo tanto, no es realmente volver a encuadernar nada. Es como llamar a 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 .


usuario570826 preguntó:

¿Qué pasa si tenemos, a = b = c = 10

Esa es exactamente la misma situación que a = b = c = [1, 2, 3] : tienes tres nombres para el mismo valor.

Pero en este caso, el valor es un int , y los int s son inmutables. En cualquier caso, puede volver a enlazar a un valor diferente (por ejemplo, a = "Now I'm a string!" ), Pero no afectará el valor original, para el cual b y c seguirán siendo nombres. La diferencia es que con una lista, puede cambiar el valor [1, 2, 3] en [1, 2, 3, 4] haciendo, por ejemplo, a.append(4) ; ya que realmente está cambiando el valor para el que b y c son nombres, b ahora b [1, 2, 3, 4] . No hay manera de cambiar el valor 10 en otra cosa. 10 es 10 para siempre, al igual que Claudia, la vampira tiene 5 para siempre (al menos hasta que sea reemplazada por Kirsten Dunst).


* Advertencia: No le des un perro caliente a Notorious BIG. Gangsta rap zombies nunca deben ser alimentados después de la medianoche.

Tos tos

 >>> a,b,c = (1,2,3) >>> a 1 >>> b 2 >>> c 3 >>> a,b,c = ({'test':'a'},{'test':'b'},{'test':'c'}) >>> a {'test': 'a'} >>> b {'test': 'b'} >>> c {'test': 'c'} >>> 

Sí, ese es el comportamiento esperado. a, b y c están configurados como tags para la misma lista. Si desea tres listas diferentes, debe asignarlas individualmente. Puede repetir la lista explícita o utilizar una de las numerosas formas de copiar una lista:

 b = a[:] # this does a shallow copy, which is good enough for this case import copy c = copy.deepcopy(a) # this does a deep copy, which matters if the list contains mutable objects 

Las declaraciones de asignación en Python no copian los objetos: vinculan el nombre a un objeto, y un objeto puede tener tantas tags como se establezca. En su primera edición, al cambiar a [0], está actualizando un elemento de la lista única a la que a, b y c se refieren. En su segundo cambio de e, está cambiando e para que sea una etiqueta para un objeto diferente (4 en lugar de 3).

En Python, todo es un objeto, también tipos de variables “simples” (int, float, etc.).

Cuando cambia un valor de variable, en realidad cambia su puntero , y si compara entre dos variables, compara sus punteros . (Para que quede claro, el puntero es la dirección en la memoria física de la computadora donde se almacena una variable).

Como resultado, cuando cambia un valor de variable interna, cambia su valor en la memoria y afecta a todas las variables que apuntan a esta dirección.

Para tu ejemplo, cuando haces:

 a = b = 5 

Esto significa que ayb apuntan a la misma dirección en la memoria que contiene el valor 5, pero cuando lo hace:

 a = 6 

No afecta a b porque a es ahora apunta a otra ubicación de memoria que contiene 6 y b aún apunta a la dirección de memoria que contiene 5.

Pero, cuando lo haces:

 a = b = [1,2,3] 

ayb, nuevamente, apunta a la misma ubicación, pero la diferencia es que si cambia uno de los valores de la lista:

 a[0] = 2 

Cambia el valor de la memoria en la que a está apuntando, pero a sigue apuntando a la misma dirección que b, y como resultado, b también cambia.

Puede usar id(name) para verificar si dos nombres representan el mismo objeto:

 >>> a = b = c = [0, 3, 5] >>> print(id(a), id(b), id(c)) 46268488 46268488 46268488 

Las listas son mutables; significa que puede cambiar el valor en su lugar sin crear un nuevo objeto. Sin embargo, depende de cómo cambie el valor:

 >>> a[0] = 1 >>> print(id(a), id(b), id(c)) 46268488 46268488 46268488 >>> print(a, b, c) [1, 3, 5] [1, 3, 5] [1, 3, 5] 

Si asigna una nueva lista a, entonces su ID cambiará, por lo que no afectará a los valores de b y c :

 >>> a = [1, 8, 5] >>> print(id(a), id(b), id(c)) 139423880 46268488 46268488 >>> print(a, b, c) [1, 8, 5] [1, 3, 5] [1, 3, 5] 

Los enteros son inmutables, por lo que no puede cambiar el valor sin crear un nuevo objeto:

 >>> x = y = z = 1 >>> print(id(x), id(y), id(z)) 507081216 507081216 507081216 >>> x = 2 >>> print(id(x), id(y), id(z)) 507081248 507081216 507081216 >>> print(x, y, z) 2 1 1 

en tu primer ejemplo a = b = c = [1, 2, 3] realmente estás diciendo:

  'a' is the same as 'b', is the same as 'c' and they are all [1, 2, 3] 

Si desea establecer ‘a’ igual a 1, ‘b’ igual a ‘2’ y ‘c’ igual a 3, intente esto:

 a, b, c = [1, 2, 3] print(a) --> 1 print(b) --> 2 print(c) --> 3 

¡Espero que esto ayude!

Lo que necesitas es esto:

 a, b, c = [0,3,5] # Unpack the list, now a, b, and c are ints a = 1 # `a` did equal 0, not [0,3,5] print(a) print(b) print(c) 

En pocas palabras, en el primer caso, está asignando varios nombres a una list . Solo se crea una copia de la lista en la memoria y todos los nombres se refieren a esa ubicación. Así que cambiar la lista usando cualquiera de los nombres modificará la lista en la memoria.

En el segundo caso, se crean múltiples copias del mismo valor en la memoria. Así que cada copia es independiente una de otra.

Gracias a todos por sus aclaraciones.

El código que hace lo que necesito podría ser este:

 #test aux=[[0 for n in range(3)] for i in range(4)] print('aux:',aux) #initialization a,b,c,d=[[0 for n in range(3)] for i in range(4)] #changing values a[0]=1 d[2]=5 print('a:',a) print('b:',b) print('c:',c) print('d:',d) 

resultado: (‘aux:’, [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]) (‘a:’, [1 , 0, 0]) (‘b:’, [0, 0, 0]) (‘c:’, [0, 0, 0]) (‘d:’, [0, 0, 5])

Saludos

Tuve un problema similar con TKInter inicializando varias variables con el mismo método:

 e_serverIP, e_serverPort, e_user, e_password = [Entry(master) for k in range(4)]