identity if - Python:¿Por qué("hola" es "hola")evalúa como verdadero?





variable string (7)


Por qué es extraño Si la cuerda es inmutable, tiene mucho sentido guardarla solo una vez. .NET tiene el mismo comportamiento.

Esta pregunta ya tiene una respuesta aquí:

¿Por qué "hello" is "hello" producir True en Python?

Leí lo siguiente here :

Si dos literales de cadena son iguales, se han puesto en la misma ubicación de memoria. Una cadena es una entidad inmutable. No se puede hacer daño.

Entonces, ¿hay un solo lugar en la memoria para cada cadena de Python? Suena bastante extraño. ¿Que está pasando aqui?




El intérprete / compilador de Python analiza los literales de cadena, es decir, la lista de caracteres citada. Cuando lo hace, puede detectar "He visto esta cadena antes" y usar la misma representación que la última vez. Puede hacerlo porque sabe que las cadenas definidas de esta manera no se pueden cambiar.




Entonces, ¿hay un solo lugar en la memoria para cada cadena de Python?

No, solo los que el intérprete ha decidido optimizar, que es una decisión basada en una política que no forma parte de la especificación del lenguaje y que puede cambiar en diferentes versiones de CPython.

p.ej. en mi instalación (2.6.2 Linux):

>>> 'X'*10 is 'X'*10
True
>>> 'X'*30 is 'X'*30
False

de manera similar para ints:

>>> 2**8 is 2**8
True
>>> 2**9 is 2**9
False

Por lo tanto, no confíe en que 'string' es 'string': incluso si solo mira la implementación de C, no es seguro.




Python (como Java, C, C ++, .NET) utiliza el agrupamiento de cadenas / interning. El intérprete se da cuenta de que "hola" es lo mismo que "hola", por lo que optimiza y usa la misma ubicación en la memoria.

Otro regalo: "hell" + "o" is "hello" ==> True




Creo que si dos variables (no solo cadenas) contienen el mismo valor, el valor se almacenará solo una vez, no dos, y ambas variables apuntarán a la misma ubicación. Esto ahorra memoria.




Las cadenas literales probablemente se agrupen según su hash o algo similar. Dos de las mismas cadenas literales se almacenarán en la misma memoria, y las referencias se refieren a eso.

 Memory        Code
-------
|          myLine = "hello"
|        /
|hello  <
|        \
|          myLine = "hello"
-------



Por cierto, la razón por la que el recuento de líneas para la versión C ++ es mayor que el recuento de la versión de Python es que la marca eof solo se establece cuando se intenta leer más allá de eof. Así que el bucle correcto sería:

while (cin) {
    getline(cin, input_line);

    if (!cin.eof())
        line_count++;
};




python identity string-comparison object-comparison