Is it preferred to do:
if x is y:
return True
or
if x == y
return True
Same thing for "is not"
Is it preferred to do:
if x is y:
return True
or
if x == y
return True
Same thing for "is not"
Depends. is
and is not
do identity comparison, which is good for None
, Ellipsis
, or making sure that two objects are the same. Otherwise, use ==
or !=
.
x is y
is different than x == y
.
x is y
is true if and only if id(x) == id(y)
-- that is, x
and y
have to be one and the same object (with the same id
s).
For all built-in Python objects (like strings, lists, dicts, functions, etc.), if x is y
, then x == y
is also True. However, this is not guaranteed in general. Strictly speaking, x == y
is true if and only if x.__eq__(y)
returns True.
It is possible to define an object x
with a __eq__
method which always returns False, for example, and this would cause x == y
to return False, even if x is y
.
So the bottom line is, x is y
and x == y
are completely different tests.
Consider this for example:
In [1]: 0 is False
Out[1]: False
In [2]: 0 == False
Out[2]: True
PS. Instead of
if x is y:
return True
else:
return False
it is more Pythonic to write
return x is y
And similarly,
if x == y:
return True
else:
return False
can be replaced with
return x == y
x is y
compares the identities of the two objects, and is asking 'are x
and y
different names for the same object?' It is equivalent to id(x) == id(y)
.
x == y
uses the equality operator and asks the looser question 'are x
and y
equal?' For user defined types it is equivalent to x.__eq__(y)
.
The __eq__
special method should represent 'equalness' for the objects, for example a class representing fractions would want 1/2 to equal 2/4, even though the 'one half' object couldn't have the same identity as the 'two quarters' object.
Note that it is not only the case that a == b
does not imply a is b
, but also the reverse is true. One is not in general a more stringent requirement than the other. Yes, this means that you can have a == a
return False
if you really want to, for example:
>>> a = float('nan')
>>> a is a
True
>>> a == a
False
In practice though is
is almost always a more specific comparison than ==
.
==
and !=
are object value comparison operatorsis
and is not
are object identity comparison operatorsas others have already said, is
(and is not
) are only when you actually care that a pair of variables are referring to exactly the same object. in most cases, you really don't care at all, so you would use ==
and !=
.
however, what you may start to notice, if you look at a lot of Python code, is that is
(and is not
) are more likely to be used when comparing against True
, False
, and None
. the main reason for this is that those objects are singletons, meaning there is exactly one instance of each of those values. why does that matter? well, this leads to another reason... speed.
with ==
and !=
, the interpreter has to pull up both referred objects in order to make a comparison (of whether they're the same or not), while is
and is not
simply just check the values of the objects they're referring to. with this said, you can see that the latter pair will perform faster because you don't have to fetch the objects themselves in order to make the comparison. here's a speed test from a couple of years back where we concluded that for one-offs, it's not a big deal, but if it's called a gazillion times in a tight loop, well, it will start to add up.
http://mail.python.org/pipermail/tutor/2008-June/062708.html
bottom line is that you can use object identity comparisons for checking against True
, False
, and None
, and everything else should use straight-up equality operators. we won't get into interned integers nor bound instance methods, or anything like that here. :-)