Otro duplicado preguntaba por qué dos cadenas iguales generalmente no son idénticas, lo que realmente no se responde aquí:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Entonces, ¿por qué no son la misma cadena? Especialmente dado esto:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Dejemos la segunda parte por un momento. ¿Cómo podría ser cierto el primero?
El intérprete tendría que tener una "tabla interna", una tabla que mapee valores de cadena a objetos de cadena, por lo que cada vez que intente crear una nueva cadena con el contenido 'abc'
, obtendrá el mismo objeto. Wikipedia tiene una discusión más detallada sobre cómo funciona la pasantía.
Y Python tiene una mesa de prácticas de cadenas; puede internar cadenas manualmente con el sys.intern
método.
De hecho, Python puede internar automáticamente cualquier tipo inmutable, pero no está obligado a hacerlo. Diferentes implementaciones incorporarán diferentes valores.
CPython (la implementación que estás usando si no sabes qué implementación estás usando) auto-interna enteros pequeños y algunos singleton especiales como False
, pero no cadenas (o enteros grandes, o tuplas pequeñas, o cualquier otra cosa). Puedes ver esto con bastante facilidad:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, pero ¿por qué eran z
y w
eran idénticos?
Ese no es el intérprete que interviene automáticamente, son los valores de plegado del compilador.
Si la misma cadena en tiempo de compilación aparece dos veces en el mismo módulo (lo que exactamente significa esto es difícil de definir, que no es lo mismo que un literal de cadena, porque r'abc'
, 'abc'
y 'a' 'b' 'c'
son todas diferentes literales, pero la misma cadena, pero fácil de entender intuitivamente), el compilador solo creará una instancia de la cadena, con dos referencias.
De hecho, el compilador puede ir aún más lejos: el optimizador 'ab' + 'c'
puede convertirlo a 'abc'
, en cuyo caso se puede plegar junto con una 'abc'
constante en el mismo módulo.
Nuevamente, esto es algo que Python está permitido pero no está obligado a hacer. Pero en este caso, CPython siempre pliega cadenas pequeñas (y también, por ejemplo, tuplas pequeñas). (Aunque el compilador declaración por declaración del intérprete interactivo no ejecuta la misma optimización que el compilador módulo a la vez, no verá exactamente los mismos resultados de forma interactiva).
Entonces, ¿qué debe hacer al respecto como programador?
Pues nada. Casi nunca tienes motivos para preocuparte si dos valores inmutables son idénticos. Si desea saber cuándo puede usar en a is b
lugar de a == b
, está haciendo la pregunta incorrecta. Solo utilícelo siempre, a == b
excepto en dos casos:
- Para comparaciones más legibles con los valores singleton como
x is None
.
- Para valores mutables, cuando necesite saber si la mutación
x
afectará al y
.