Mi Google-fu me ha fallado.
En Python, ¿son equivalentes las siguientes dos pruebas de igualdad?
n = 5
# Test one.
if n == 5:
print 'Yay!'
# Test two.
if n is 5:
print 'Yay!'
¿Es esto cierto para los objetos en los que compararía instancias (por listejemplo)?
De acuerdo, este tipo de respuestas a mi pregunta:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
Entonces ==, ¿el valor de las pruebas donde las ispruebas para ver si son el mismo objeto?

echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foosalida:False True False.b = a[:]parte de copia de la lista del operador de división, así que edité tu respuesta para tener un comentario allí. Parece que acabo de llegar al umbral para no tener que revisar mis ediciones antes de que se apliquen, así que espero que sea genial para ti. De todos modos, aquí hay una referencia útil sobre cómo copiar listas que encontré y tuve que hacer referencia para averiguar qué estaba haciendo: stackoverflow.com/a/2612815/4561887==. Entonces,5.0por ejemplo, es un valor de coma flotante, mientras que5es un número entero. Pero5.0 == 5aún regresaráTrueporque representan el mismo valor. En términos de rendimiento y tipificación de pato,isel intérprete siempre prueba al comparar las direcciones de memoria del operando, mientras==que depende del objeto decidir si se define como igual a otra cosa.1000 is 10**3se evalúa como Verdadero en Python 3.7 ya que 10 ** 3 es tipoint. Pero se1000 is 1e3evalúa como False ya que 1e3 es typefloat.1000 is 10**3verdad es o no depende de la implementación y depende de que el compilador evalúe previamente la expresión10**3.x=10; 1000 is x**3evalúa aFalse.Hay una regla general simple que le indica cuándo usar
==ois.==es por la igualdad de valores . Úselo cuando desee saber si dos objetos tienen el mismo valor.ises para referencia de igualdad . Úselo cuando desee saber si dos referencias se refieren al mismo objeto.En general, cuando compara algo con un tipo simple, generalmente verifica la igualdad de valor , por lo que debe usar
==. Por ejemplo, la intención de su ejemplo es probablemente verificar si x tiene un valor igual a 2 (==), no sixse refiere literalmente al mismo objeto que 2.Algo más a tener en cuenta: debido a la forma en que funciona la implementación de referencia de CPython, obtendrá resultados inesperados e inconsistentes si usa por error
ispara comparar la igualdad de referencia en enteros:Eso es más o menos lo que esperábamos:
aybtienen el mismo valor, pero son entidades distintas. ¿Pero qué hay de esto?Esto es inconsistente con el resultado anterior. ¿Que está pasando aqui? Resulta que la implementación de referencia de Python almacena en caché objetos enteros en el rango -5..256 como instancias singleton por razones de rendimiento. Aquí hay un ejemplo que demuestra esto:
Esta es otra razón obvia para no usar
is: el comportamiento se deja a las implementaciones cuando se usa erróneamente para la igualdad de valores.fuente
a=500yb=500, solo quería señalar que si estableceaybun número entero entre [-5, 256], ena is brealidad regresaTrue. Más información aquí: stackoverflow.com/q/306313/7571052==determina si los valores son iguales, mientras queisdetermina si son exactamente el mismo objeto.fuente
Sí, tienen una diferencia muy importante.
==: verifique la igualdad: la semántica es que los objetos equivalentes (que no son necesariamente el mismo objeto) probarán como iguales. Como dice la documentación :is: verifique la identidad: la semántica es que el objeto (como se mantiene en la memoria) es el objeto. De nuevo, la documentación dice :Por lo tanto, verificar la identidad es lo mismo que verificar la igualdad de las ID de los objetos. Es decir,
es lo mismo que:
¿Dónde
idestá la función incorporada que devuelve un número entero que "se garantiza que es único entre los objetos existentes simultáneamente" (verhelp(id)) y dóndeaybcualquier objeto arbitrario.Otras direcciones de uso
Debe usar estas comparaciones para su semántica. Use
ispara verificar la identidad y==para verificar la igualdad.Entonces, en general, usamos
ispara verificar la identidad. Esto suele ser útil cuando buscamos un objeto que solo debería existir una vez en la memoria, denominado "singleton" en la documentación.Los casos de uso para
isincluyen:NoneLos casos de uso habituales para
==incluyen:El caso de uso general, nuevamente, para
==, es que el objeto que desea puede no ser el mismo objeto, sino que puede ser uno equivalentePEP 8 direcciones
PEP 8, la guía de estilo oficial de Python para la biblioteca estándar también menciona dos casos de uso para
is:Inferir igualdad de identidad
Si
ises cierto, la igualdad generalmente se puede inferir: lógicamente, si un objeto es él mismo, entonces debería probarse como equivalente a sí mismo.En la mayoría de los casos, esta lógica es cierta, pero se basa en la implementación del
__eq__método especial. Como dicen los documentos ,y en aras de la coherencia, recomienda:
Podemos ver que este es el comportamiento predeterminado para los objetos personalizados:
El contrapositivo también suele ser cierto: si algo prueba que no es igual, generalmente se puede inferir que no son el mismo objeto.
Dado que las pruebas de igualdad se pueden personalizar, esta inferencia no siempre es válida para todos los tipos.
Una excepción
Una excepción notable es
nan: siempre prueba que no es igual a sí mismo:Verificar la identidad puede ser una verificación mucho más rápida que verificar la igualdad (lo que puede requerir la verificación recursiva de los miembros).
Pero no puede ser sustituido por igualdad donde puede encontrar más de un objeto como equivalente.
Tenga en cuenta que al comparar la igualdad de listas y tuplas se supondrá que la identidad de los objetos es igual (porque esta es una comprobación rápida). Esto puede crear contradicciones si la lógica es inconsistente, como lo es para
nan:Un cuento de precaución:
La pregunta está intentando usar
ispara comparar enteros. No debe suponer que una instancia de un entero es la misma instancia que una obtenida por otra referencia. Esta historia explica por qué.Un comentarista tenía un código que se basaba en el hecho de que los enteros pequeños (-5 a 256 inclusive) son singletons en Python, en lugar de verificar la igualdad.
Funcionó en desarrollo. Puede haber pasado algunas pruebas unitarias.
Y funcionó en producción, hasta que el código verificó un número entero mayor que 256, momento en el cual falló en producción.
Esta es una falla de producción que podría haberse detectado en la revisión del código o posiblemente con un verificador de estilo.
Permítanme enfatizar: no lo use
ispara comparar enteros.fuente
is Nonees una excepción, pero eso== Nonetambién funciona ...ispara compararEnums.¿Cuál es la diferencia entre
isy==?==yisson diferentes comparaciones! Como otros ya dijeron:==compara los valores de los objetos.iscompara las referencias de los objetos.En Python los nombres se refieren a objetos, por ejemplo en este caso
value1y sevalue2refieren a unaintinstancia que almacena el valor1000:Porque se
value2refiere al mismo objetoisy==daráTrue:En el siguiente ejemplo, los nombres
value1y sevalue2refieren a diferentesintinstancias, incluso si ambos almacenan el mismo número entero:Debido a que el mismo valor (entero) se almacena
==seráTrue, por eso a menudo se denomina "valor de comparación". Sin embargois, regresaráFalseporque estos son objetos diferentes:¿Cuándo usar cuál?
Generalmente
ises una comparación mucho más rápida. Es por eso que CPython almacena en caché (o quizás reutilizaciones sería el mejor término) ciertos objetos como enteros pequeños, algunas cadenas, etc. Pero esto debe tratarse como un detalle de implementación que podría (incluso si es poco probable) cambiar en cualquier momento sin previo aviso.Solo debe usar
issi usted:desea comparar un valor con una constante de Python . Las constantes en Python son:
NoneTrue1False1NotImplementedEllipsis__debug__int is intoint is float)np.ma.maskeddel módulo NumPy)En cualquier otro caso, debe usar
==para verificar la igualdad.¿Puedo personalizar el comportamiento?
Hay algún aspecto
==que no se ha mencionado ya en las otras respuestas: es parte del "modelo de datos" de Pythons . Eso significa que su comportamiento se puede personalizar utilizando el__eq__método. Por ejemplo:Este es solo un ejemplo artificial para ilustrar que el método realmente se llama:
Tenga en cuenta que por defecto (si no
__eq__se puede encontrar otra implementación de la clase o las superclases)__eq__utilizais:Por lo tanto, es importante implementarlo
__eq__si desea "más" que solo una comparación de referencia para clases personalizadas.Por otro lado, no puede personalizar los
ischeques. Siempre se comparará solo si tiene la misma referencia.¿Estas comparaciones siempre devolverán un valor booleano?
Debido a que
__eq__se puede volver a implementar o anular, no se limita a returnTrueoFalse. Se podría devolver nada (pero en la mayoría de los casos se debe devolver un valor lógico!).Por ejemplo, con matrices NumPy
==, devolverá una matriz:¡Pero los
ischeques siempre volveránTrueoFalse!1 Como Aaron Hall mencionó en los comentarios:
En general, no debe hacer ninguna
is Trueois Falseverificaciones porque normalmente se usan estas "verificaciones" en un contexto que convierte implícitamente la condición a un valor booleano (por ejemplo, en unaifdeclaración). Entonces, hacer lais Truecomparación y el elenco booleano implícito está haciendo más trabajo que solo hacer el elenco booleano, y se limita a los booleanos (que no se considera pitónico).Como PEP8 menciona:
fuente
is: los nombres que apuntan a booleanos deben verificarse con un contexto booleano, comoif __debug__:oif not __debug__:. Nunca debe hacerif __debug__ is True:oif __debug__ == True:, además, una constante es simplemente un valor semántico constante, no un singleton, por lo tanto, verificarisen ese caso no es semánticamente correcto. Te reto a que encuentres una fuente que respalde tus afirmaciones; no creo que encuentres una.None,True,Falsey__debug__son lo que se llama "valor semántico constante", porque no pueden ser reasignados. Pero todos ellos son solteros.is Trueoif Falsecheck (pero sí, estos son bastante raros, pero si los haces puedes usarlosis). Es por eso que incluso CPython los usa a veces (por ejemplo aquí o aquí )Son completamente diferentes .
iscomprueba la identidad del objeto, mientras que==comprueba la igualdad (una noción que depende de los tipos de los dos operandos).Es solo una coincidencia afortunada que "
is" parece funcionar correctamente con enteros pequeños (por ejemplo, 5 == 4 + 1). Esto se debe a que CPython optimiza el almacenamiento de enteros en el rango (-5 a 256) al hacerlos únicos . Este comportamiento depende totalmente de la implementación y no se garantiza su preservación en todo tipo de operaciones de transformación menores.Por ejemplo, Python 3.5 también crea cadenas cortas simples, pero cortarlas interrumpe este comportamiento:
fuente
https://docs.python.org/library/stdtypes.html#comparisons
ispruebas de identidad==pruebas de igualdadCada valor entero (pequeño) se asigna a un solo valor, por lo que cada 3 es idéntico e igual. Este es un detalle de implementación, aunque no forma parte de la especificación del lenguaje
fuente
Tu respuesta es correcta. El
isoperador compara la identidad de dos objetos. El==operador compara los valores de dos objetos.La identidad de un objeto nunca cambia una vez que se ha creado; puede pensar en ello como la dirección del objeto en la memoria.
Puede controlar el comportamiento de comparación de los valores de los objetos definiendo un
__cmp__método o un método de comparación rico como__eq__.fuente
Eche un vistazo a la pregunta de desbordamiento de pila El operador "es" de Python se comporta inesperadamente con los enteros .
En general, se reduce a que "
is" verifica si son el mismo objeto, no solo iguales entre sí (los números por debajo de 256 son un caso especial).fuente
En pocas palabras,
iscomprueba si dos referencias apuntan al mismo objeto o no.==comprueba si dos objetos tienen el mismo valor o no.fuente
Como dijo John Feminella, la mayoría de las veces usará == y! = Porque su objetivo es comparar valores. Solo me gustaría clasificar lo que harías el resto del tiempo:
Hay una única instancia de NoneType, es decir, None es un singleton. En consecuencia
foo == Noneyfoo is Nonesignifica lo mismo. Sin embargo, laisprueba es más rápida y se debe usar la convención Pythonicfoo is None.Si usted está haciendo un poco de introspección o curioseaba con la recolección de basura o la comprobación de si la cadena hecha a la medida internar aparato funciona o cosas por el estilo, entonces es probable que tenga un caso de uso para el
fooque esbar.True y False también son (ahora) singletons, pero no hay un caso de
foo == Trueuso ni un caso de uso parafoo is True.fuente
La mayoría de ellos ya respondieron al punto. Solo como una nota adicional (basada en mi comprensión y experimentación pero no de una fuente documentada), la declaración
de las respuestas anteriores deben leerse como
. Llegué a esta conclusión en base a la prueba a continuación:
Aquí el contenido de la lista y la tupla son los mismos, pero el tipo / clase es diferente.
fuente
La diferencia de Python entre es y es igual (==)
Aquí hay un ejemplo para demostrar la similitud y la diferencia.
fuente
A medida que las otras personas en esta publicación responden a la pregunta en detalle, enfatizaría principalmente la comparación entre
isy==para cadenas que pueden dar diferentes resultados e instaría a los programadores a usarlas cuidadosamente.Para la comparación de cadenas, asegúrese de usar en
==lugar deis:Fuera:
Pero en el siguiente ejemplo
==yisobtendremos resultados diferentes:Fuera:
Conclusión:
Use con
iscuidado para comparar entre cadenasfuente