identity versus equality for None in Python
Various Python guides say to use x is None
instead of x == None
. Why is that? Equality is used for comparing values, so it seems natural to ask if x
has the value None
, denoted with ==
and not is
. Can someone explain why is
is the preferred form and show an example where the two do not give the same answer?
Thanks.
Solution 1:
The reason people use is
is because there is no advantage to using ==
. It is possible to write objects that compare equal to None
, but it is uncommon.
class A(object):
def __eq__(self, other):
return True
print A() == None
Output:
True
The is
operator is also faster, but I don't consider this fact important.
Solution 2:
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.
Solution 3:
PEP 8 says: "Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators." Here is a quite good explanation why:
http://jaredgrubb.blogspot.com/2009/04/python-is-none-vs-none.html