3 minutes
Difference between comparisons with == and is in Python
In Python, two operators exist to perform equality comparisons: == and is. Often you can read instructions like “When comparing to None, always use is instead of ==”, but the real reason is not explained. However, looking at the language expression specification section of the Python manual you can find the difference: “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.” This means the expressions “a is b” only returns True if both a and b point to the exact same object instance. Hence, you should always use is when you want to compare against specific instances. For the advice about using is to compare with None this means that there is only a single instance of None. The same is true also for Ellipsis.
Not knowing the difference in comparison operators can actually lead to quite confusing results because of Python’s operator overloading abilities. Imagine you need to check in some code whether an arbitrary variable you receive is Ellipsis or anything else. If you use == instead of “is” for that check, this might work in many cases but it might also be destroyed completely if that variable points to an object with a custom implementation of the **eq** function:
>>> a = "a test string"
>>> a == Ellipsis
False
>>> import numpy as np
>>> a = np.array(range(5))
>>> a == Ellipsis
array([False, False, False, False, False], dtype=bool)
>>> a is Ellipsis
False
>>> a == None
False
In the example, string behaves correctly for the test against Ellipsis, but comparing against a numpy ndarray (highlighted lines) doesn’t yield a boolean value as expect, but instead another array containing booleans, because ndarray implements **eq** and maps the comparison operator to an element-wise comparison. This probably results in an exception in production use. Lines 10 and 11 show that “is” ignores the custom comparison method and correctly resutls the expected boolean value.
Finally it is noteworthy that **eq** implementation of ndarray seems to be aware of the fact that people constantly compare against None with ==. This is the reasons why the last two lines of the source code listing return only a single boolean value and not a list. However, you should normally not rely on this fact as it is not given for all comparison implementations.
Other languages actually have a similar concept but they expose it in a more obvious way. In Java the == operator always checks for object identity and you explicitly need to implement and call the equals method if you want to have a custom comparison.