Why does the following behave unexpectedly in Python?
>>> a = 256 >>> b = 256 >>> a is b True # This is an expected result >>> a = 257 >>> b = 257 >>> a is b False # What happened here? Why is this False? >>> 257 is 257 True # Yet the literal numbers compare properly
I am using Python 2.5.2. Trying some different versions of Python, it appears that Python 2.3.3 shows the above behaviour between 99 and 100.
Based on the above, I can hypothesize that Python is internally implemented such that “small” integers are stored in a different way than larger integers and the
is operator can tell the difference. Why the leaky abstraction? What is a better way of comparing two arbitrary objects to see whether they are the same when I don’t know in advance whether they are numbers or not?
Take a look at this:
>>> a = 256 >>> b = 256 >>> id(a) 9987148 >>> id(b) 9987148 >>> a = 257 >>> b = 257 >>> id(a) 11662816 >>> id(b) 11662828
Here’s what I found in the Python 2 documentation, “Plain Integer Objects” (It’s the same for Python 3):
The current implementation keeps an
array of integer objects for all
integers between -5 and 256, when you
create an int in that range you
actually just get back a reference to
the existing object. So it should be
possible to change the value of 1. I
suspect the behaviour of Python in
this case is undefined. 🙂