Si bien esta pregunta no tiene ningún uso real en la práctica, tengo curiosidad por saber cómo Python realiza prácticas de cadenas. He notado lo siguiente.
>>> "string" is "string"
True
Esto es lo que esperaba.
También puedes hacer esto.
>>> "strin"+"g" is "string"
True
¡Y eso es bastante inteligente!
Pero no puedes hacer esto.
>>> s1 = "strin"
>>> s2 = "string"
>>> s1+"g" is s2
False
¿Por qué Python no evaluaría s1+"g"
y se daría cuenta de que es lo mismo que s2
apuntar a la misma dirección? ¿Qué está pasando realmente en ese último bloque para que vuelva False
?
"string1" + "s2"
,10 + 3*20
, etc.) en tiempo de compilación, pero los límites resultantes secuencias a sólo 20 elementos (para evitar que[None] * 10**1000
se expanda excesivamente su código de bytes). Es esta optimización la que colapsó"strin" + "g"
en"string"
; el resultado tiene menos de 20 caracteres.intern()
función.intern
función en Python 3, se mueve a sys.internCaso 1
>>> x = "123" >>> y = "123" >>> x == y True >>> x is y True >>> id(x) 50986112 >>> id(y) 50986112
Caso 2
>>> x = "12" >>> y = "123" >>> x = x + "3" >>> x is y False >>> x == y True
Ahora, su pregunta es por qué la identificación es la misma en el caso 1 y no en el caso 2.
En el caso 1, ha asignado una cadena literal
"123"
ax
yy
.Dado que las cadenas son inmutables, tiene sentido que el intérprete almacene la cadena literal solo una vez y apunte todas las variables al mismo objeto.
Por lo tanto, ve la identificación como idéntica.
En el caso 2, está modificando
x
mediante concatenación. Ambosx
yy
tienen los mismos valores, pero no la misma identidad.Ambos apuntan a diferentes objetos en la memoria. Por lo tanto, han vuelto diferentes
id
y elis
operadorFalse
fuente
id(x) != id(x)
por ejemplo, porque la cadena se movió en el proceso de evaluación.x = "12" + "3"
enx = "123"
(concatenación de dos literales de cadena en una sola expresión) para que la asignación realmente realice la búsqueda y encuentre la misma cadena "interna" que paray = "123"
.