El
is
operador no coincide con los valores de las variables, sino con las propias instancias.
que significa realmente?
Declaro dos variables nombradas x
y y
asignando los mismos valores en ambas variables, pero devuelve falso cuando uso el is
operador.
Necesito una aclaración. Aquí está mi código.
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
Respuestas:
No entendiste lo
is
que prueba el operador. Prueba si dos variables apuntan al mismo objeto , no si dos variables tienen el mismo valor.De la documentación para el
is
operador :Utilice el
==
operador en su lugar:Esto imprime
True
.x
yy
son dos listas separadas :Si usa la
id()
función , verá esox
yy
tendrá diferentes identificadores:pero si se va a asignar
y
ax
continuación, ambos apuntan al mismo objeto:y
is
muestra que ambos son el mismo objeto, regresaTrue
.Recuerde que en Python, los nombres son solo etiquetas que hacen referencia a valores ; puede hacer que varios nombres apunten al mismo objeto.
is
le dice si dos nombres apuntan a un mismo objeto.==
le dice si dos nombres se refieren a objetos que tienen el mismo valor.fuente
A is B
es lo mismo queid(A) == id(B)
.id(A)
en una variable y luego esperevariable == id(B)
seguir funcionando; siA
se eliminó mientras tanto,B
podría haber recibido la misma ubicación de memoria.\n
>>> y = 5\n
>>> x es y\n
Verdadero\n
>>> x == y\n
Verdadero\n
>>>\n
Otro duplicado preguntaba por qué dos cadenas iguales generalmente no son idénticas, lo que realmente no se responde aquí:
Entonces, ¿por qué no son la misma cadena? Especialmente dado esto:
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:OK, pero ¿por qué eran
z
yw
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 dea == b
, está haciendo la pregunta incorrecta. Solo utilícelo siempre,a == b
excepto en dos casos:x is None
.x
afectará aly
.fuente
w
yz
son idénticos debido a los valores de plegado del compilador, ¿por qué esto también funciona en el REPL, incluso usandoid()
para verificar las referencias? Uso de REPL en Python 3.7is
solo devuelve verdadero si en realidad son el mismo objeto. Si fueran iguales, también aparecería un cambio en uno en el otro. He aquí un ejemplo de la diferencia.fuente
A raíz de una pregunta duplicada , esta analogía podría funcionar:
fuente
is
yis not
son los dos operadores de identidad en Python.is
El operador no compara los valores de las variables, sino que compara las identidades de las variables. Considera esto:El ejemplo anterior muestra que la identidad (también puede ser la dirección de memoria en Cpython) es diferente para ambos
a
yb
(aunque sus valores son los mismos). Es por eso que cuando dicea is b
que devuelve falso debido a la falta de coincidencia en las identidades de ambos operandos. Sin embargo, cuando dicea == b
, devuelve verdadero porque la==
operación solo verifica si ambos operandos tienen el mismo valor asignado.Ejemplo interesante (para la nota extra):
En el ejemplo anterior, aunque
a
yb
son dos variables diferentes, sea is b
devolvióTrue
. Esto se debe a que el tipo dea
esint
que es un objeto inmutable. Entonces, Python (supongo que para ahorrar memoria) asignó el mismo objeto ab
cuando se creó con el mismo valor. Entonces, en este caso, las identidades de las variables coincidieron ya is b
resultaron serTrue
.Esto se aplicará a todos los objetos inmutables:
Espero que ayude.
fuente
-5
o mayor que256
en Python será Falso. Python almacena en caché números en el rango [-5, 256].x is y
es lo mismo queid(x) == id(y)
comparar la identidad de los objetos.Como @ tomasz-kurgan señaló en el comentario a continuación, el
is
operador se comporta de manera inusual con ciertos objetos.P.ej
Árbitro;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
fuente
Como puede comprobar aquí a pequeños enteros. Los números por encima de 257 no son entradas pequeñas, por lo que se calcula como un objeto diferente.
Es mejor usar
==
en su lugar en este caso.Más información está aquí: http://docs.python.org/2/c-api/int.html
fuente
X apunta a una matriz, Y apunta a una matriz diferente. Esas matrices son idénticas, pero el
is
operador observará esos punteros, que no son idénticos.fuente
is
funcionalidad del operador lo demuestra.id
menos que lo solicites.Compara la identidad del objeto, es decir, si las variables se refieren al mismo objeto en la memoria. Es como
==
en Java o C (al comparar punteros).fuente
Un ejemplo sencillo con frutas
Salida:
Si intentas
La salida es diferente:
Eso es porque el operador == compara solo el contenido de la variable. Para comparar las identidades de 2 variables use el operador is
Para imprimir el número de identificación:
fuente
El
is
operador no es más que una versión en inglés de==
. Debido a que los ID de las dos listas son diferentes, la respuesta es falsa. Puedes probar:* Porque las ID de ambas listas serían las mismas
fuente
is
no es 'una versión en inglés de==
'