"is" operator behaves unexpectedly with integers

identity, int, operators, python, python-internals

Solution

Take a look at this:

>>> a = 256
>>> b = 256
>>> id(a) == id(b)
True
>>> a = 257
>>> b = 257
>>> id(a) == id(b)
False

Here's what I found in the documentation for "Plain Integer Objects":

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, integers 256 are identical, but 257 are not. This is a CPython implementation detail, and not guaranteed for other Python implementations.

Problem

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?

Original source

Related problems