Why should "num3 is num4" result in False? [duplicate]

There is this post on Instagram where the author says if num3 and num4 are set to 257 and num3 is num4 is evaluated you should get False.

I have revised the code adding some conditions but I am getting True. I saw that integers until 256 are assigned the same memory bucket for the same value but not for 257 onward. So what is happening?

num1 = 256 num2 = 256 if num1 == num2: print(True) num3 = 257 num4 = 257 if num3 == num4: print(True) if num3 is num4: print(True) else: print(False) 
3

2 Answers

is will return True if two variables point to the same object

== if the objects referred to by the variables are equal.

Run in script:

is returns True

Because both num3 and num4 point to the same object:

# id() to get the unique identifier of an object print(id(num3) , id(num4)) 55080624 55080624 

== also returns True

num3 = 257 num4 = 257 

as both refer to <class 'int'> 257

Run in REPL :

is returns False

Because both num3 and num4 point to the different objects:

# id() to get the unique identifier of an object print(id(num3) , id(num4)) 34836272 39621264 

== returns True

num3 = 257 num4 = 257 

as both refer to <class 'int'> 257

The reason you have different result is from Why does the `is` operator behave differently in a script vs the REPL?

When you run code in a .py script, the entire file is compiled into a code object before executing it. In this case, CPython is able to make certain optimizations - like reusing the same instance for the integer 300.

So in your case, both num3 and num4 refer to <class 'int'> 257. in REPL you have different object ids, however after the file is compiled and optimized to same object id if you run them in script.

Regards to the different behaviors of 256 and 257 :

"is" operator behaves unexpectedly with integers

What's with the integer cache maintained by the interpreter?

in short, objects representing values from -5 to +256 are created at startup time, so if you have number range -5 to 256 you get the same object id in REPL, for any int <-5 and > 256,they will be assigned to a new object id.

for example :

num5 = -6 num6 = -6 print(id(num5),id(num6)) 39621232 39621136 num7 = 258 num8 = 258 print(id(num7),id(num8)) 39621296 39621328 
3

If you look at the post again, you can see that num3 == num4 is True, but num3 is num4 is False. This has to do with item ids. == compares the values of the variables, while is compares their ids. You can see each of their ids using id(num3) and id(num4). They should be different when values are higher than 256. Reason for this is that Python stores low number values automatically, and variables assigned to these low numbers will point to the same id. Python does this because they are so commonly used. But larger numbers aren't created until Python needs them. So variables are given their own ids.

Edit:

There seems to be different behavior when running a script vs. REPL. The original Instagram post was using REPL, and I replicated the False comparison using REPL. Running a script evaluated True for me though.

6

You Might Also Like