Python: Diferencia entre los operadores == e is

Una de las características más inusuales de python son los operadores == e is, ya que a simple vista parecen funcionar de la misma forma. En realidad, bajo ciertas circunstancias lo hacen.

Ejemplo 1. Números entre -5 y 256

# Ejemplo 1.
>>>> a = -5
>>>> b = -5
>>>> a == b	# forma correcta de comparar numeros
True		# resultado esperado
>>>> a is b	# forma incorrecta (pero al parecer valida)
True		# resultado esperado (pero no el correcto)

# si se compara un numero fuera de este rango
# se mostrara un comportamiento distinto
>>>> x = 257
>>>> y = 257
>>> x == y
True		# resultado esperado
>>> x is y
False		# ¿?


Prueba de identidad

Volviendo al primer ejemplo, es necesario verificar la identidad de las variables a, b, x y y para entender por qué se devuelve True o False en ciertas comparaciones.

En el caso de a y b:

>>>> a = -5
>>>> b = -5
>>>> a == b
True		# resultado esperado
>>>> a is b
True		# resultado esperado (pero no el correcto)

Python trata de manera distinta a los números que se encuentren en este rango. Según este extracto de la documentación de python:

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. 🙂

Es decir, cuando se crea una variable entera dentro de este rango, en realidad se obtiene una referencia del objeto (número) existente dentro del arreglo de enteros.

Es posible verificarlo probando la identidad de los objetos a y b.

>>> id(a), id(b)
(15841352, 15841352)

Ya que ambos objetos a y b tienen el mismo id (dirección de memoria), se trata en realidad de la misma instancia y no de dos. Dado que se trata de la misma instancia, al comparar a y b con is se obtendrá True:

>>>> a is b
True		# a y b representan la misma instancia del numero -5

Si realizamos la misma comparación de id con las variables x y y, se obtendrá un resultado distinto:

>>> id(x), id(y)
(16125072, 16125048)

Aunque ambas variables x y y contengan el mismo valor, representan instancias distintas. Dado que se trata de instancias distintas, al comparar x y y se obtendrá False:

>>> x is y
False		# mismo valor 257, diferente instancia

Más sobre esto en stackoverflow y en davequinn.com.

Ejemplo 2. Comparación de listas o [] is [] … ¿False?

Otro ejemplo que encontré al consultar un poco es este:

# Ejemplo 2
>>> [] is not []
True

Se trata de otro ejemplo de identidad. Visto de otra forma:

>>> [] is []
False         # ¿no es lo mismo?
>>> [] == []
True          # ¿o si lo es?

Al igual que en el ejemplo 1, los operadores realizan la comparación de forma distinta. En el caso de is, esto es lo que se menciona en la documentación de python:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

Es decir x is y sólo devolverá True si y sólo si x y y son el mismo objeto. x is not y devuelve el valor de verdad inverso. Al hablar del mismo objeto se refiere a la misma instancia.

Volviendo al ejemplo, se trata de dos instancias (listas) distintas. Una forma más clara de verlo es asignando variables:

# Ejemplo 2, ahora con variables
>>> x = []
>>> y = []
>>> x is y
False			# devuelve False ya que x y y son instancias distintas
>>> x is not y
True			# devuelve el valor inverso a la comparación x is y
>>> id(x), id(y)
(140115630930688, 140115630930760)	# realmente son instancias distintas

Dado que x y y son instancias distintas y no el mismo objeto, el operador is devuelve False.

Ahora bien, en el caso del operador ==, esto es lo que se menciona en la documentación de python:


Tuples and lists are compared lexicographically using comparison of corresponding elements. This means that to compare equal, each element must compare equal and the two sequences must be of the same type and have the same length.

Es decir, en el caso de tuplas y listas, la comparación se hace en base al valor, tipo y la longitud. Dado que x y y tienen los mismos elementos (ninguno), son del mismo tipo y ambas listas tienen la misma longitud, se consideran iguales y se devolverá True.

2 comentarios en “Python: Diferencia entre los operadores == e is

Deja un comentario