The is
keyword tests identity. It is not a comparison operator like ==
. Using is
does more than test whether two arguments have the same value and/or the same internal structure: namely, it tests whether the two actually refer to the same object in memory. There are numerous implications to this, one of them being that is
cannot be overloaded, and another being that behavior differs between mutable and immutable types. For example, consider the following:
>>> l1 = range(5)
>>> l2 = range(5)
>>> l1 == l2
True
>>> l1 is l2
False
>>> l3 = l1
>>> l1 is l3
True
>>> s1 = "abcde"
>>> s2 = "abcde"
>>> s1 == s2
True
>>> s1 is s2
True
Here, because lists are mutable, they cannot share a location in memory, and consequently is
and ==
yield discrepant results. On the other hand, strings are immutable, and therefore their memory may be pooled in some cases. Basically, is
can only reliably be used for simple, immutable types, or in instances when multiple names point to exactly the same object in memory (such as the use of l3
in the above example), and its use indicates a desire to test identity rather than value. I would expect is
to be slightly faster than ==
because it doesn't perform method lookup, but I could be mistaken. Of course, for complex container objects like lists or dicts, is
should be much faster than ==
(O(1) vs. O(n), presumably). That said, the speed issue is mostly a moot point, as the two should not be regarded as interchangeable.