2

First scenario

A=1
B=1
A is B #output is True

Second scenario

A=[1]
B=[1]
A is B #output is false

I know list is a by reference data type and hence the second scenario makes sense. But I don't get why the first scene gives an output True. The memory location for integers should be different right? Or does it point to the same location if the value is similar?

some_programmer
  • 3,268
  • 4
  • 24
  • 59
Nitin Sai
  • 29
  • 2
  • 1
    This has nothing to do with by-reference/by-value. In the first case, both `A` and `B` point to the same object in memory - `1`. This is possible because there is a cache in Python for some integers. In your second code you create 2 different lists (even thought their content is the same) so obviously `A` and `B` are not pointing to the same object... – Tomerikoo Aug 13 '20 at 09:37
  • In python every thing is object since an integer is treated as an object too so it is stored in an pool memory so if next variable is assigned the same value they both point to same value in the pool memory that's why comparing integer returns true. and I highly recommend DON'T USE IS FOR COMPARINIG INTEGER VALUES. https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers have a look at this. – gagangaur Aug 13 '20 at 09:37
  • 1
    Does this answer your question? [What's with the integer cache maintained by the interpreter?](https://stackoverflow.com/questions/15171695/whats-with-the-integer-cache-maintained-by-the-interpreter) – Tomerikoo Aug 13 '20 at 09:41
  • Thanks a lot. Will keep that in mind – Nitin Sai Aug 13 '20 at 09:51

2 Answers2

3

When comparing the memory adresses of 2 integers, you can see that they are stored in the same location:

x = 1
y = 1
print(id(x) == id(y))
True

However when we edit one of the variables.

x = 1
y = 1
x += 1
print(id(x) == id(y))
False

As seen in "is" operator behaves unexpectedly with integers. The python interpreter caches integers from -5 up to 256. This way all variables that fall within this range will point to those memory adresses. If a variable changes, however, it will no longer point to those adresses. For instance:

a = 256; 
b = 256;
print(id(a) == id(b))
c = 257;
d = 257;
print(id(c) == id(d))
True
False

However I have seen some online python interpreters return True for both of them.

Simon Tulling
  • 176
  • 1
  • 7
0

You are true for the lists.

For the integer parts, the Language Reference Manual says that it is an implementation detail:

after a = 1; b = 1, a and b may or may not refer to the same object with the value one, depending on the implementation

In the CPython reference implementation, a is b is true, because:

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.

For integers outside of the cached range, il may depend on whether you are in immediate or compiled mode: if Python can see a full module at once, it may use optimization to have a and b refere to to same object it is does not change the behaviour. But as those are only implementation detail you should never rely on two identifiers sharing or not the same object for non reference type.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252