¿Por qué la comparación de cadenas mediante '==' o 'is' produce a veces un resultado diferente?

Tengo un programa en Python en el que dos variables tienen el valor 'public'. En una expresión condicional tengo la comparación var1 es var2 que falla, pero si la cambio por var1 == var2 devuelve True.

Ahora bien, si abro mi intérprete de Python y hago la misma comparación "es", tiene éxito.

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

¿Qué me estoy perdiendo aquí?

Solución

es es una prueba de identidad, == es una prueba de igualdad. lo que ocurre en tu código se emularía en el intérprete así:

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

así que, no es de extrañar que no sean lo mismo, ¿verdad?

En otras palabras: es es el id(a) == id(b)

Comentarios (12)

La palabra clave es es una prueba de identidad del objeto mientras que == es una comparación de valores.

Si utiliza es, el resultado será verdadero si y sólo si el objeto es el mismo. Sin embargo, == será verdadero siempre que los valores del objeto sean iguales.

Comentarios (0)

Creo que tiene que ver con el hecho de que, cuando la comparación "es" evalúa a falso, se utilizan dos objetos distintos. Si evalúa a true, significa que internamente se está usando exactamente el mismo objeto y no se está creando uno nuevo, posiblemente porque los creaste en una fracción de 2 segundos más o menos y como no hay un gran espacio de tiempo entre ellos se optimiza y se usa el mismo objeto.

Esta es la razón por la que deberías usar el operador de igualdad ==, no es, para comparar el valor de un objeto de cadena.

>>> s = 'one'
>>> s2 = 'two'
>>> s is s2
False
>>> s2 = s2.replace('two', 'one')
>>> s2
'one'
>>> s2 is s
False
>>> 

En este ejemplo, hice que 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 no lo asigné inicialmente a uno, si lo hubiera hecho los habría hecho el mismo objeto.

Comentarios (2)