Why (0-6) is -6 = False?
All integers from -5 to 256 inclusive are cached as global objects sharing the same address with CPython, thus the is
test passes.
This artifact is explained in detail in http://www.laurentluce.com/posts/python-integer-objects-implementation/, and we could check the current source code in http://hg.python.org/cpython/file/tip/Objects/longobject.c.
A specific structure is used to refer small integers and share them so access is fast. It is an array of 262 pointers to integer objects. Those integer objects are allocated during initialization in a block of integer objects we saw above. The small integers range is from -5 to 256. Many Python programs spend a lot of time using integers in that range so this is a smart decision.
This is only an implementation detail of CPython and you shouldn't rely on this. For instance, PyPy implemented the id
of integer to return itself, so (0-6) is -6
is always true even if they are "different objects" internally; it also allows you to configure whether to enable this integer caching, and even set the lower and upper bounds. But in general, objects retrieved from different origins will not be identical. If you want to compare equality, just use ==
.
Why and how does the Python interpreter remember literal objects
There's a range of small numbers that are kept as singletons within Python; any reference will always return the same object and they will never be garbage collected.
>>> for x,y in enumerate(range(1000)):
if x is not y:
print x,y
break
257 257
What does 'is' operator do in Python?
You missed that is not
is an operator too.
Without is
, the regular not
operator returns a boolean:
>>> not None
True
not None
is thus the inverse boolean 'value' of None
. In a boolean context None
is false:
>>> bool(None)
False
so not None
is boolean True
.
Both None
and True
are objects too, and both have a memory address (the value id()
returns for the CPython implementation of Python):
>>> id(True)
4440103488
>>> id(not None)
4440103488
>>> id(None)
4440184448
is
tests if two references are pointing to the same object; if something is the same object, it'll have the same id()
as well. is
returns a boolean value, True
or False
.
is not
is the inverse of the is
operator. It is the equivalent of not (op1 is op2)
, in one operator. It should not be read as op1 is (not op2)
here:
>>> 1 is not None # is 1 a different object from None?
True
>>> 1 is (not None) # is 1 the same object as True?
False
Getting weird results while subtraction manipulation in python
Don't use is
for equality testing - it's the identity operator, and two equal objects are not necessarily identical (i. e. residing under the same address in your computer's memory). Some small integers may be cached and reused but not all of them which is why you're seeing different results here.
Additionally, this behavior is implementation-dependent, so you can't rely on this always being the case.
How to tell when 2 variables with same value will have different identities?
The small integers are getting interned.
Short ints with small values (typically between -1 and 99
inclusive) are "interned" -- whenever a result has such a value,
an existing short int with the same value is returned. This is
not done for long ints with the same values.
Further,
But code may exist that uses 'is' for comparisons of short ints and
happens to work because of this interning. Such code may fail
if used with long ints.)
However, this isn't behavior that should be relied upon as it is implementation-specific. It isn't going to work for larger integers and interning isn't guaranteed, so you shouldn't be using is
here.
Other than integers, strings may also be interned.
(PEP-0237)
Related Topics
Django Db Settings 'Improperly Configured' Error
How to Use Multiprocessing Queue in Python
How to Resolve Typeerror: Can Only Concatenate Str (Not "Int") to Str
In Pytest, What Is the Use of Conftest.Py Files
Does a File Object Automatically Close When Its Reference Count Hits Zero
Installing Pip Packages to $Home Folder
Split a String with Unknown Number of Spaces as Separator in Python
Converting Python Dict to Kwargs
"Pythonic" Method to Parse a String of Comma-Separated Integers into a List of Integers
Google Colab: How to Read Data from My Google Drive
How to Change Default Anaconda Python Environment
Pygame.Error: Video System Not Initialized
Multiple Variables in a 'With' Statement
Paramiko Ssh Die/Hang with Big Output