0

Running interpreter

>>> x = 5000
>>> y = 5000
>>> print(x is y)
False

running the same in script using python test.py returns True

What the heck?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
kAldown
  • 610
  • 2
  • 8
  • 27
  • 2
    You are investigating immutable interning -- something that is variable, unpredictable and implementation dependent. – dawg Jul 28 '16 at 13:42
  • 1
    Whether or not two equal objects created by literals are the same object should be considered unpredictable. – chepner Jul 28 '16 at 13:44
  • 1
    Note that if you combine everything on a single line in the interactive interpreter, you get the same behavior as you see when running the commands in a file (`x=5000;y=5000;print (x is y)`). – larsks Jul 28 '16 at 13:44
  • 1
    You may find this question useful: http://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers – Tonechas Jul 28 '16 at 14:15
  • 1
    @wjandrea To be pedantic, Python *only* has literals for immutable objects. `[...]` is a display, not a literal :) – chepner May 15 '22 at 22:01
  • @chepner Ah whoops, you're right. I forgot what "literal" means and I was thinking it meant "formed by syntax elements instead of by a call" :) – wjandrea May 15 '22 at 22:04
  • 1
    I used to use the fact that displays can contain non-constant values as an explanation for the distinction, but then f-strings came along. ¯\\_(ツ)_/¯ – chepner May 15 '22 at 22:12

2 Answers2

3

The is operator only returns True when the two operands reference the exact same object. Whether the interpreter chooses to create new values or re-use existing ones is an implementation detail. CPython (the most commonly used implementation) is clearly quite happy having several different integer objects that will compare equal, but not identical.

Similarly there are no guarantees that the interpreter's behaviour will be the same as far as memory allocation and value creation are concerned. When running interactively quite a lot happens between the execution of successive statements. Running non-interactively none of that stuff (bind value of the expression to the _ variable, print out the value followed by a prompt, etc.) needs to happen, and so it's easier for the interpreter to re-use a just-created value.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • so how should I debug this behaviour, guessing that python can blame me working interactively? – kAldown Jul 28 '16 at 16:01
  • 1
    There is not "debugging" this behaviour - it isn't a bug. Why do you need to know whether two different `500`s are the same object or not? The CPython interpreter optimises certain commonly-used values, but this does not affect results of performance in any way at all. – holdenweb Jul 28 '16 at 16:11
  • Because this is an example of code, for testing me on a vacant position. – kAldown Jul 28 '16 at 16:13
  • 1
    If the answer "this behaviour will not necessarily be seen on all implementations" isn't a good enough answer to get you the job I would suggest you look at working somewhere else. The identity of immutable values is unpredictable. – holdenweb Jul 28 '16 at 16:14
  • Yeap thats right. Unpredictable isn't good enough for me. Thats why I'm not satisfied this kind of answer and will dig until I realize that, or even find an answer why – kAldown Jul 28 '16 at 16:18
  • As [the documentation](https://docs.python.org/3/c-api/long.html#integer-objects) says: "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. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)." Does this tell you what you need to know? – holdenweb Jul 28 '16 at 16:30
  • @kAldown: If you want to learn everything about all the arbitrary decisions Python makes in cases where it makes no promises, you're going to have to start [reading the source](https://hg.python.org/cpython/file/3.5) yourself. – user2357112 Jul 28 '16 at 17:33
  • And again, I underline: this behaviour is no part of the language specification, it's simply a space optimisation adopted by the CPython devs. – holdenweb Jul 29 '16 at 07:46
3

Python allocates some numbers at start.

for x,y in zip(range(256,258),range(256,258)):
    print(x is y)

x=y=5000
print(x is y)

This will print on my machine:

True
False
True

The first print is True because it was in the allocated range and both x and y refer to the same number. The False indicates that both x and y will create an integer object and these won't be the same. The last one is True because I specifically told Python to make x and y the same object. If you want to check equality, use == instead of is.

Gábor Fekete
  • 1,343
  • 8
  • 16
  • Yeap, I'm quite asking why does them refer same object, but not another one, in case int is immutable – kAldown Jul 28 '16 at 16:07