Why do these statements evaluate the way they do?

Stephen Hansen me at ixokai.io
Sat May 7 03:49:29 EDT 2016


On Fri, May 6, 2016, at 11:36 PM, Anthony Papillion wrote:
> I'm trying to figure out why the following statements evaluate the way
> they do and I'm not grasping it for some reason. I'm hoping someone can
> help me.
> 
> 40+2 is 42 #evaluates to True
> But
> 2**32 is 2**32 #evaluates to False
> 
> This is an example taken from a Microsoft blog on the topic. They say the
> reason is because the return is based on identity and not value but, to
> me, these statements are fairly equal.

Yes, those statements are fairly *equal*. But you are not testing
*equality*. The "is" operator is testing *object identity*.

>>> a = 123456
>>> b = 123456
>>> a is b
False
>>> a == b
True

Equality means, "do these objects equal the same", identity means, "are
these specific objects the exact same objects".

In the above, a and b are different objects. There's two objects that
contain a value of 12345. They are equal (see the == test), but they are
different objects. 

If you write on a piece of paper "12345", and I write on a piece of
paper "12345", are those two pieces of paper identical? Of course not.
Your paper is in your hand, mine is in mine. These are different pieces
of paper. Just look at them: they're clearly not the same thing. That
said, if you look at the number they contain, they're the same value.

Our two pieces of paper are equivalent, but they're different objects.

This might get confusing for you because:

>>> a = 123
>>> b = 123
>>> a is b
True
>>> a == b 
True

This happens because Python caches small integers, so everytime you
write '123', it re-uses that same '123' object everyone else is using.
It shares those objects as an optimization.

The long and short of it is: you should almost never use 'is' for
comparing integers (or strings). It doesn't mean what you think it does
and isn't useful to you. Compare equality.

In general, the only things you should use 'is' for is when comparing to
singletons like None, True or False (And consider strongly not comparing
against False/True with is, but instead just 'if thing' and if its True,
it passes).

Otherwise, 'is' should only be used when you're comparing *object
identity*. You don't need to do that usually. Only do it when it matters
to you that an object with value A might be equal to an object of value
B, but you care that they're really different objects.


-- 
Stephen Hansen
  m e @ i x o k a i  . i o



More information about the Python-list mailing list