Mi entendimiento fue que las cadenas de Python son inmutables.
Probé el siguiente código:
a = "Dog"
b = "eats"
c = "treats"
print a, b, c
# Dog eats treats
print a + " " + b + " " + c
# Dog eats treats
print a
# Dog
a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!
¿No debería Python haber evitado la asignación? Probablemente me esté perdiendo algo.
¿Alguna idea?
python
string
immutability
mutability
jason
fuente
fuente
id()
función.a
tendrá una identificación diferente antes y después de la asignación, lo que indica que está apuntando a diferentes objetos. Del mismo modo, con un código como,b = a
lo encontraráa
yb
tendrá la misma identificación, lo que indica que están haciendo referencia al mismo objeto.Respuestas:
Primero
a
señaló la cadena "Perro". Luego cambió la variablea
para que apunte a una nueva cadena "El perro come golosinas". En realidad, no mutó la cadena "Perro". Las cadenas son inmutables, las variables pueden apuntar a lo que quieran.fuente
Los propios objetos de cuerda son inmutables.
La variable,
a
que apunta a la cadena, es mutable.Considerar:
fuente
a.append(3)
no es lo mismo quea = a + 3
. Ni siquieraa += 3
(en lugar de la adición es equivalente a.extend
, no a.append
).+
se comporta de la misma manera para listas y cadenas: concatena creando una nueva copia y sin mutar ninguno de los operandos.append
función porque son inmutables.La variable a apunta al objeto "Perro". Es mejor pensar en la variable en Python como una etiqueta. Puede mover la etiqueta a diferentes objetos, que es lo que hizo cuando cambió
a = "dog"
aa = "dog eats treats"
.Sin embargo, la inmutabilidad se refiere al objeto, no a la etiqueta.
Si intentaras
a[1] = 'z'
convertirte"dog"
en"dzg"
, obtendrías el error:debido a que las cadenas no admiten la asignación de elementos, son inmutables.
fuente
Algo es mutable solo cuando podemos cambiar los valores contenidos en la ubicación de la memoria sin cambiar la ubicación de la memoria en sí.
El truco es: si encuentra que la ubicación de la memoria antes y después del cambio es la misma, es mutable.
Por ejemplo, la lista es mutable. ¿Cómo?
Una cuerda es inmutable. ¿Cómo lo probamos?
obtenemos
Entonces fallamos al mutar la cadena. Significa que una cuerda es inmutable.
Al reasignar, cambia la variable para que apunte a una nueva ubicación. Aquí no ha mutado la cadena, sino la propia variable. Lo siguiente es lo que está haciendo.
id
antes y después de la reasignación es diferente, por lo que esto demuestra que en realidad no está mutando, sino que apunta la variable a una nueva ubicación. Lo cual no está mutando esa cadena, sino esa variable.fuente
Una variable es solo una etiqueta que apunta a un objeto. El objeto es inmutable, pero puede hacer que la etiqueta apunte a un objeto completamente diferente si lo desea.
fuente
Considerar:
Observe que la ubicación de la memoria hexadecimal no cambió cuando almacené el mismo valor en la variable dos veces. Cambió cuando almacené un valor diferente. La cuerda es inmutable. No por fanatismo, sino porque paga la penalización de rendimiento de crear un nuevo objeto en la memoria. La variable
a
es solo una etiqueta que apunta a esa dirección de memoria. Puede modificarse para señalar cualquier cosa.fuente
La declaración
a = a + " " + b + " " + c
se puede desglosar en función de las sugerencias.a + " "
dice: dame losa
puntos a, que no se pueden cambiar, y agrega" "
a mi conjunto de trabajo actual.memoria:
+ b
dice dame a québ
apunta, que no se puede cambiar, y agrégalo al conjunto de trabajo actual.memoria:
+ " " + c
dice agregar" "
al conjunto actual. Luego, dame a quéc
apunta, que no se puede cambiar, y agrégalo al conjunto de trabajo actual. memoria:Finalmente,
a =
dice establecer mi puntero para que apunte al conjunto resultante.memoria:
"Dog"
se recupera, porque no más punteros se conectan a su parte de la memoria. Nunca modificamos la sección de memoria"Dog"
en la que residía, que es lo que se entiende por inmutable. Sin embargo, podemos cambiar qué etiquetas, si las hay, apuntan a esa sección de la memoria.fuente
fuente
Existe una diferencia entre los datos y la etiqueta a la que están asociados. Por ejemplo cuando lo haces
los datos
"dog"
se crean y se colocan bajo la etiquetaa
. La etiqueta puede cambiar, pero lo que está en la memoria no lo hará. Los datos"dog"
seguirán existiendo en la memoria (hasta que el recolector de basura los elimine) después de que lo hagaEn su programa
a
ahora ^ apunta a ^"cat"
pero la cadena"dog"
no ha cambiado.fuente
Las cadenas de Python son inmutables. Sin embargo,
a
no es una cadena: es una variable con un valor de cadena. No puede mutar la cadena, pero puede cambiar el valor de la variable a una nueva cadena.fuente
Las variables pueden apuntar a cualquier lugar que deseen. Se producirá un error si hace lo siguiente:
fuente
Los objetos de cadena de Python son inmutables. Ejemplo:
En este ejemplo podemos ver que cuando asignamos un valor diferente en un no se modifica, se crea un nuevo objeto.
Y no se puede modificar. Ejemplo:
Ocurre un error.
fuente
'mutable' significa que podemos cambiar el contenido de la cadena, 'inmutable' significa que no podemos agregar una cadena adicional.
fuente
>>> a = 'dogs'
>>> a.replace('dogs', 'dogs eat treats')
'dogs eat treats'
>>> print a
'dogs'
Inmutable, ¿no es así?
La parte de cambio de variable ya se ha discutido.
fuente
replace()
método devuelve una nueva cadena.Considere esta adición a su ejemplo
Una de las explicaciones más precisas que encontré en un blog es:
Enlace al blog: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/
fuente
Agregando un poco más a las respuestas mencionadas anteriormente.
id
de una variable cambia con la reasignación.Lo que significa que hemos mutado la variable
a
para que apunte a una nueva cadena. Ahora existen dosstring
(str) objetos:'initial_string'
conid
= 139982120425648y
'new_string'
conid
= 139982120425776Considere el siguiente código:
Ahora,
b
apunta al'initial_string'
y tiene lo mismoid
quea
tenía antes de la reasignación.Por lo tanto,
'intial_string'
no se ha mutado.fuente
Resumiendo:
No inmutable:
Inmutable:
Este es un error en Python 3 porque es inmutable. Y no es un error en Python 2 porque claramente no es inmutable.
fuente
La función incorporada
id()
devuelve la identidad de un objeto como un número entero. Este número entero generalmente corresponde a la ubicación del objeto en la memoria.Inicialmente, 'a' se almacena en la ubicación de memoria 139831803293008, ya que el objeto de cadena es inmutable en Python si intenta modificar y reasignar la referencia se eliminará y será un puntero a una nueva ubicación de memoria (139831803293120).
fuente
fuente
Esta imagen da la respuesta. Por favor leelo.
fuente
Simplemente concatenamos los dos valores de cadena. Nunca cambiamos el valor de (a). Justo ahora (a) representa otro bloque de memoria que tiene el valor "dogdog". Porque en el backend, una variable nunca representa dos bloques de memoria al mismo tiempo. El valor de (a) antes de la concatenación era "perro". Pero después de eso (a) representa el "perro-perro", porque ahora (a) en el representante de backend. el bloque que tiene el valor "dogdog". Y "perro" es rep. por (b) y "perro" no se cuenta como valor de basura hasta que (b) represente el "perro".
La confusión es que representamos los bloques de memoria (que contienen datos o información) en el backend con el mismo nombre de variable.
fuente
Puede hacer que una matriz numpy sea inmutable y usar el primer elemento:
luego:
o
fuente