1

I have this code

l = 40000
m = 40000
print(type(l),type(m))
if l is m:
  print("same")
else:
  print("nope")

Taking reference from here I was hoping id to be different since the value are not falling in range of (-2,256). Please let me know if I am missing out on something

Myself using Python-3.8.3(32bit) on windows Platform

delve123
  • 47
  • 5
  • 1
    Does this answer your question? ["is" operator behaves unexpectedly with integers](https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers) – Kelly Bundy Aug 01 '20 at 12:14

1 Answers1

3

This is due to a simple optimization at the bytecode compilation stage; if the same constant appears in the same code more than once, it is created only once, and each use of the constant will refer to the same instance.

We can investigate the bytecode with the dis module:

>>> import dis
>>> dis.dis('l = 40000\nm=40000')
  1           0 LOAD_CONST               0 (40000)
              2 STORE_NAME               0 (l)

  2           4 LOAD_CONST               0 (40000)
              6 STORE_NAME               1 (m)
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE
>>> dis.dis('l = 40000\nm=40001')
  1           0 LOAD_CONST               0 (40000)
              2 STORE_NAME               0 (l)

  2           4 LOAD_CONST               1 (40001)
              6 STORE_NAME               1 (m)
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

Note that in the first case where both constants are 40000, the two LOAD_CONST operations both load constant #0, but in the second case, 40000 is constant #0 and 40001 is constant #1.

Also, you will usually get different results if you do this on separate lines in the REPL, since each line in the REPL is compiled and executed as a separate code object, so they cannot share constants:

>>> l = 50000
>>> m = 50000
>>> id(l)
140545755966480
>>> id(m)
140545755966448

But if you do both in one line in the REPL, the same instance of the constant is used again, because it's just one line compiled to one code object, so the constant can be shared:

>>> p = 60000; q = 60000
>>> id(p)
140545755966576
>>> id(q)
140545755966576
kaya3
  • 47,440
  • 4
  • 68
  • 97