Python WAT!? Integer Cache
Check out the following Python code:
>>> x = 256 >>> x is 256 True >>> y = 257 >>> y is 257 False
WAT! Why is Python doing this?
The answer is twofold:
ischecks whether 2 things are the same object, not if they’re equal
- Python caches integers in the range
The is operator tests whether two things point to the same object not if they are equal. To check equality we should use
If we use integers outside of the range
[-5, 256], we can see that they can be equal but refer to different objects:
>>> a = 257 >>> b = 257 >>> a is b False >>> a == b True
So why treat integers from
[-5, 256] different from other integers? The answer is efficiency. As explained in the official docs:
“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 small integers in the range
[-5, 256] are actually stored in the same object! We can prove this by using the built-in id function to return the “identity” of an object, eg. its actual address in memory.
>>> c = 1 >>> d = 1 >>> id(c) 4399848112 >>> id(d) 4399848112
Note: Your actual address in memory will differ from mine, but the address will be the same for both integers, which in Python are just objects.
Understanding how Python works under the hood–its actual implementation in C–is fascinating. And since Python has fantastic documentation, you can find not just the official documentation and source code, but also the discussion of why things are they way they are.
For example, the behavior of Long Integers and Integers in Python 3 was actually proposed back in 2001! And for further reading, there was a major change from Python 2 to Python 3 regarding the treatment of integers which also impacted division on a profound level. Read more here.