The interpreter doesn't have to allocate some memory and create a 1
value if it already has one lying around it can use. As long as the value is immutable, that is, but ints are immutable in Python.
CPython happens to pre-create values for a whole range of small ints. The exact range has changed a couple times over the decades (and is configurable at build time), but obviously any collection of "small ints" is going to include 1
.
This pre-creation doesn't happen, in CPython, for floats, or large ints, or non-empty tuples or strings—but they can end up identical anyway. In particular, if the compiler sees the same value twice in the same compilation unit, for a type it knows to be immutable, it can merge them. You generally only see this in module constants, not at the interactive interpreter, because interactively, each statement is a separate compilation unit. But:
>>> a = 1.0
>>> b = 1.0
>>> a is b
False
>>> c, d = 1.0, 1.0
>>> c is d
True
A different Python implementation might do things differently. (And there's one other trick just within CPython, string interning, which can be even more complicated to guess the outcome of in 3.4 and later.)
The takeaway is:
- Never assume that two separately-created but equal-valued immutables are identical.
- But never assume they aren't identical, either.
If you find yourself using is
with an int, string, or any other open-ended immutable type, you're probably doing something wrong. (Or intentionally exploring how your interpreter works, of course.)