Tengo un programa Python donde dos variables se establecen en el valor 'public'
. En una expresión condicional tengo la comparación var1 is var2
que falla, pero si la cambio a var1 == var2
ella, regresa True
.
Ahora, si abro mi intérprete de Python y hago la misma comparación "es", tiene éxito.
>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True
¿Que me estoy perdiendo aqui?
input = raw_input("Decide (y/n): ")
. En este caso, una entrada de "y" yif input == 'y':
devolverá "True" mientrasif input is 'y':
que devolverá False.Respuestas:
is
es prueba de identidad,==
es prueba de igualdad. lo que sucede en su código se emularía en el intérprete así:así que no es de extrañar que no sean lo mismo, ¿verdad?
En otras palabras:
is
es elid(a) == id(b)
fuente
==
vs.equals()
en Java. La mejor parte es que Python==
no es análogo a Java==
.None
valor único . Entonces siempre tiene la misma identificación.Otras respuestas aquí son correctas:
is
se usa para la comparación de identidad , mientras que==
se usa para la comparación de igualdad . Como lo que le importa es la igualdad (las dos cadenas deben contener los mismos caracteres), en este caso, elis
operador simplemente está equivocado y debería usarlo en su==
lugar.La razón por la que
is
funciona de manera interactiva es que (la mayoría) los literales de cadena están internados por defecto. De Wikipedia:Entonces, cuando tiene dos literales de cadena (palabras que están literalmente escritas en el código fuente de su programa, rodeadas de comillas) en su programa que tienen el mismo valor, el compilador de Python internará automáticamente las cadenas, haciéndolas ambas almacenadas en el mismo ubicación de memoria (Tenga en cuenta que esto no siempre sucede, y las reglas para cuando esto sucede son bastante complicadas, ¡así que no confíe en este comportamiento en el código de producción!)
Dado que en su sesión interactiva ambas cadenas se almacenan en la misma ubicación de memoria, tienen la misma identidad , por lo que el
is
operador funciona como se esperaba. Pero si construye una cadena por algún otro método (incluso si esa cadena contiene exactamente los mismos caracteres), entonces la cadena puede ser igual , pero no es la misma cadena , es decir, tiene una identidad diferente , porque es almacenado en un lugar diferente en la memoria.fuente
==
yis
según el tipo de verificación que desee. Si le preocupa que las cadenas sean iguales (es decir, que tengan el mismo contenido), siempre debe usarlas==
. Si le importa si dos nombres de Python se refieren a la misma instancia de objeto, debe usarlosis
. Es posible que necesiteis
si está escribiendo código que maneja muchos valores diferentes sin preocuparse por su contenido, o si sabe que solo hay uno de algo y desea ignorar otros objetos que fingen ser esa cosa. Si no está seguro, elija siempre==
.La
is
palabra clave es una prueba de identidad de objeto, mientras que==
es una comparación de valores.Si lo usa
is
, el resultado será verdadero si y solo si el objeto es el mismo objeto. Sin embargo,==
será cierto siempre que los valores del objeto sean los mismos.fuente
Una última cosa a tener en cuenta es que puede usar la
sys.intern
función para asegurarse de obtener una referencia a la misma cadena:Como se señaló anteriormente, no debe usarse
is
para determinar la igualdad de cadenas. Pero esto puede ser útil para saber si tiene algún tipo de requisito extraño para usaris
.Tenga en cuenta que la
intern
función solía estar integrada en Python 2 pero se movió alsys
módulo en Python 3.fuente
is
es prueba de identidad,==
es prueba de igualdad. Lo que esto significa es queis
es una forma de verificar si dos cosas son las mismas , o simplemente equivalentes.Digamos que tienes un
person
objeto simple . Si se llama 'Jack' y tiene '23' años, es equivalente a otro Jack de 23 años, pero no es la misma persona.Son de la misma edad, pero no son la misma instancia de persona. Una cadena puede ser equivalente a otra, pero no es el mismo objeto.
fuente
jack1.age = 99
, eso no cambiarájack2.age
. Eso es porque son dos instancias diferentes, entoncesjack1 is not jack2
. Sin embargo, pueden igualarse entre síjack1 == jack2
si su nombre y su edad son los mismos. Se vuelve más complicado para las cadenas, porque las cadenas son inmutables en Python, y Python a menudo reutiliza la misma instancia. Me gusta esta explicación porque usa los casos simples (un objeto normal) en lugar de los casos especiales (cadenas).Esta es una nota al margen, pero en Python idiomático, a menudo verá cosas como:
Esto es seguro, porque se garantiza que habrá una instancia del Objeto nulo (es decir, Ninguno) .
fuente
Si no está seguro de lo que está haciendo, use '=='. Si tiene un poco más de conocimiento al respecto, puede usar 'es' para objetos conocidos como 'Ninguno'.
De lo contrario, terminarás preguntándote por qué las cosas no funcionan y por qué sucede esto:
Ni siquiera estoy seguro de que algunas cosas se mantengan igual entre diferentes versiones / implementaciones de Python.
fuente
Desde mi experiencia limitada con python,
is
se utiliza para comparar dos objetos para ver si son el mismo objeto en oposición a dos objetos diferentes con el mismo valor.==
se usa para determinar si los valores son idénticos.Aquí hay un buen ejemplo:
s1
es una cadena unicode ys2
es una cadena normal. No son del mismo tipo, pero tienen el mismo valor.fuente
Creo que tiene que ver con el hecho de que, cuando la comparación 'es' se evalúa como falsa, se utilizan dos objetos distintos. Si se evalúa como verdadero, eso significa que internamente está usando el mismo objeto exacto y no está creando uno nuevo, posiblemente porque los creó en una fracción de 2 segundos más o menos y porque no hay una gran brecha de tiempo entre está optimizado y usa el mismo objeto
Es por eso que debería usar el operador de igualdad
==
, nois
, para comparar el valor de un objeto de cadena.En este ejemplo, hice s2, que era un objeto de cadena diferente previamente igual a 'uno' pero no es el mismo objeto que
s
, porque el intérprete no usó el mismo objeto ya que inicialmente no lo asigné a 'uno', si lo hubiera hecho les habría hecho el mismo objeto.fuente
.replace()
embargo, usarlo como ejemplo en este contexto probablemente no sea el mejor, porque su semántica puede ser confusa.s2 = s2.replace()
será siempre crear un nuevo objeto de cadena, asignar el nuevo objeto de cadena as2
, y luego disponer del objeto cadena ques2
utiliza para el punto a. Entonces, incluso si lo hicieras = s.replace('one', 'one')
, aún obtendría un nuevo objeto de cadena.Creo que esto se conoce como cadenas "internas". Python hace esto, también Java, y también C y C ++ cuando compila en modos optimizados.
Si usa dos cadenas idénticas, en lugar de desperdiciar memoria creando dos objetos de cadena, todas las cadenas internas con el mismo contenido apuntan a la misma memoria.
Esto da como resultado que el operador "is" de Python devuelva True porque dos cadenas con el mismo contenido apuntan al mismo objeto de cadena. Esto también sucederá en Java y en C.
Sin embargo, esto solo es útil para ahorrar memoria. No puede confiar en él para probar la igualdad de cadena, porque los diversos intérpretes y compiladores y motores JIT no siempre pueden hacerlo.
fuente
Estoy respondiendo la pregunta a pesar de que la pregunta es demasiado antigua porque ninguna de las respuestas anteriores cita la referencia del idioma
En realidad, el operador verifica la identidad y == el operador verifica la igualdad,
De la referencia del lenguaje:
Los tipos afectan a casi todos los aspectos del comportamiento del objeto. Incluso la importancia de la identidad del objeto se ve afectada en cierto sentido: para los tipos inmutables, las operaciones que calculan nuevos valores en realidad pueden devolver una referencia a cualquier objeto existente con el mismo tipo y valor, mientras que para los objetos mutables esto no está permitido . Por ejemplo, después de a = 1; b = 1, ayb pueden o no referirse al mismo objeto con el valor uno, dependiendo de la implementación, pero después de c = []; d = [], cyd están garantizados para referirse a dos listas vacías diferentes, únicas y recién creadas. (Tenga en cuenta que c = d = [] asigna el mismo objeto a c y d.)
entonces, de la declaración anterior, podemos inferir que las cadenas que son de un tipo inmutable pueden fallar cuando se verifican con "es" y pueden ser exitosas cuando se marcan con "es"
Lo mismo aplica para int, tuple que también son tipos inmutables
fuente
La
==
equivalencia del valor de prueba del operador. Elis
operador prueba la identidad del objeto, Python prueba si los dos son realmente el mismo objeto (es decir, viven en la misma dirección en la memoria).En este ejemplo, Python solo creó un objeto de cadena, y ambos,
a
y seb
refiere a él. La razón es que Python almacena en caché internamente y reutiliza algunas cadenas como una optimización, realmente solo hay una cadena 'banana' en la memoria, compartida por a y b; Para desencadenar el comportamiento normal, debe usar cadenas más largas:Cuando crea dos listas, obtiene dos objetos:
En este caso, diríamos que las dos listas son equivalentes, porque tienen los mismos elementos, pero no idénticos, porque no son el mismo objeto. Si dos objetos son idénticos, también son equivalentes, pero si son equivalentes, no son necesariamente idénticos.
Si se
a
refiere a un objeto y usted lo asignab = a
, ambas variables se refieren al mismo objeto:fuente
is
comparará la ubicación de la memoria. Se utiliza para la comparación a nivel de objeto.==
comparará las variables en el programa. Se utiliza para verificar en un nivel de valor.is
comprueba la equivalencia de nivel de dirección==
comprueba la equivalencia de nivel de valorfuente
is
es una prueba de identidad,==
es una prueba de igualdad (consulte la documentación de Python ).En la mayoría de los casos, si
a is b
, entoncesa == b
. Pero hay excepciones, por ejemplo:Por lo tanto, solo puede usar
is
para pruebas de identidad, nunca pruebas de igualdad.fuente