views:

464

answers:

4

Is it preferred to do:

if x is y:
    return True

or

if x == y
    return True

Same thing for "is not"

+4  A: 

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 !=.

Ignacio Vazquez-Abrams
+25  A: 

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 ids).

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
unutbu
That was really helpful. Thank you!
ensnare
@ensnare: No problem! Glad I could help.
unutbu
I'm being a bit picky, but it's not correct that you need `x == y` to be true before `x is y` can be true. They are independent tests. Admittedly in practice you'd be hard-pressed to find a sensible counter-example, but the `__eq__` special method could just return `False` or raise an exception.
Scott Griffiths
@Scott: Thank you for the correction!
unutbu
Why the parens around the return value? Why not just `return x == y`?
Rosarch
@Rosarch:Thanks for the correction. There is no reason for it except to indulge a nervous tic I have.
unutbu
+10  A: 

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 ==.

Scott Griffiths
The fractions example is really on the spot, Great Scott. :)
ΤΖΩΤΖΙΟΥ
+5  A: 
  • == and != are object value comparison operators
  • is and is not are object identity comparison operators

as 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. :-)

wescpy
Good point about comparing to singletons. On the subject of speed it's worth noting that `if a == True:` is slower than `if a is True:` which in turn is slower than just `if a:` (at least for built-in types in my tests). Often just using `a` or `not a` is the quickest option although they're not quite semantically the same as `a is True` or `a is None` etc.
Scott Griffiths
So, what about comparing ints, like `1 is 1` or `1 == 1`?
Rosarch
altho they're both equivalent when using small ints (currently) in the `range(-5, 256)`, those are not publicized numbers and can change in any release, so it's safer just to use `==` in all cases except `None`, `True`, and `False` (and perhaps a few others).
wescpy