3

I am new to Python so my question may seem obvious. But according to W3Schools two variables are only the same under an 'is' operator if they reference the same object. So my question is, why does following return True? I thought Python creates two separate memory locations for them?

a = 500
b = 500

print(a == b) # True
print(a is b) # True, why is this true?
Mysasas
  • 91
  • 5
  • 1
    There’s most likely a constant pool for literals. Try running a loop and at some point, `is` test will return false. – Abhijit Sarkar Oct 15 '21 at 19:33
  • 1
    Does this answer your question? [Is there a difference between "==" and "is"?](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is) – veedata Oct 15 '21 at 19:33
  • In many languages Int is value variable not reference variable. I suppose this is the case – zolty13 Oct 15 '21 at 19:33
  • CPython is known to intern small integers, but that's from -5 to 256 iirc. So if you do `x = 255; x is 255`, you get `True`, but if you do `x = 1000; x is 1000` you get `False`. It's likely that within the same expression, CPython is reusing the integer for the same literals. This implementation weirdness is why you're warned to do `==` instead of `is` for some immutable literals. The effective identity for immutable objects is their value, so use `==`. – BatWannaBe Oct 15 '21 at 19:45

3 Answers3

4

Are you sure that works for the value 500?

Python 3.8.10 (default, Jun  2 2021, 10:49:15)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 500
>>> b = 500
>>> a is b
False
>>> b = 100
>>> a = 100
>>> a is b
True
>>>

Preallocation in Python

In Python, upon startup, Python3 keeps an array of integer objects, from -5 to 256. For example, for the int object, marcos called NSMALLPOSINTS and NSMALLNEGINTS are used:

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
Py_ssize_t quick_int_allocs;
Py_ssize_t quick_neg_int_allocs;
#endif

What does this mean? This means that when you create an int from the range of -5 and 256, you are actually referencing to the existing object.

Reference: https://medium.com/@kjowong/everything-is-an-object-in-python-928f2a7d3e15

Mandraenke
  • 3,086
  • 1
  • 13
  • 26
0

it's usually a matter of optimization. it will split when u change one of the values (and occupy 2 places in memory)

  • It's an optimization, yes, but not the one you suggest. `a = 100; b = 100; a is b` prints `True`. Then, yes, `a = 500` will split it, but `a = 500; a = 100; a is b` print `True` again, splitting and unsplitting. @Mandraenke's answer is the correct one. – joanis Oct 15 '21 at 19:44
0

Difference between == and is operator in Python The Equality operator (==) compares the values of both the operands and checks for value equality. Whereas the 'is' operator checks whether both the operands refer to the same object or not (present in the same memory location)

Ref: https://www.geeksforgeeks.org/difference-operator-python/#:~:text=The%20Equality%20operator%20(%3D%3D),in%20the%20same%20memory%20location).

bhavesh
  • 56
  • 4