2

Consider the following code:

x = 50000000
y = 50000000

print(hex(id(x)), hex(id(y)))
print(x is y)

This gives:

0x23ef28ec930 0x23ef28ec930
True

Now I was lead to believe that for small values python uses optimisation to cache these in memory. But it the number is quite clearly larger than this value which I believe is 256.

Why is it not when I declare these they are stored separately in memory?

Further to this if I add in the line y+=1 just before the print statement then x and y are stored in separate locations in memory and x is y is False. I would have thought that as the are both the same object in memory that incrementing y would increment x also.

Clearly I am missing something fundamental and would appreciate it being cleared up.

As a further point does this behaviour depend on the variable type? What about if x,y are not ints but lists, strings or any other object?

Thanks!

zepsaces
  • 33
  • 3
  • It gives me different result. `0x7f907030acf0 0x7f907030a8b0`;`False` You must have done something wrong. – Pygirl Jul 08 '20 at 17:47
  • @Pygirl Did you reproduce the example exactly as stated? Running in Python 3.7.7 on Windows produced the same result as in the question. – Musab Guma'a Jul 08 '20 at 17:50
  • @Pygirl: The behavior is probably not guaranteed one way or another. – luther Jul 08 '20 at 17:51
  • I tried in ubuntu. python 3.7.3 – Pygirl Jul 08 '20 at 17:51
  • I think this is largely due to how cpython handles memory addressing. In the example given, both variables point to the same address, and hence `is` returns `True` as it compares memory addresses. Incrementing changes the value which `y` points to and hence a new memory address is assigned. I do not know, however, in which cases the cpython interpreter would favor assigning different memory addressing to variables storing equal values, such as in @Pygirl 's case. – Musab Guma'a Jul 08 '20 at 17:57
  • Does this helps: https://stackoverflow.com/questions/55347581/why-does-the-is-operator-behave-differently-in-a-script-vs-the-repl? – Pygirl Jul 08 '20 at 18:02
  • @MusabGuma'a: I can reproduce it if I make a function and put it inside that. The above posted link answer this behavior. – Pygirl Jul 08 '20 at 18:05

2 Answers2

0

python use referencing for more efficient memory usage. So, instead of two variables that share the same value and occupying two separate locations in memory, python references one of them to the other.

https://docs.python.org/2.0/ext/refcounts.html

Thulfiqar
  • 393
  • 7
  • 14
0
x = 50000000

Here, Python creates an int and stores it at 0x23ef28ec930.

y = 50000000

Here, the interpreter was able to somehow detect that the number already exists in the program, and so used the same object for y that it uses for x. Since these are number literals, the number 50000000 may have been stored at compile time and then used for both of these assignments.

As far as I know, Python makes no guarantees about whether or not identical immutable values will have the same address. You should not rely on this behavior except when dealing with singletons, like None, True, and False.

Further to this if I add in the line y+=1 just before the print statement then x and y are stored in separate locations in memory and x is y is False. I would have thought that as the are both the same object in memory that incrementing y would increment x also.

ints are immutable. When you do y += 1, you are assigning a new value to y, which makes it different from x.

As a further point does this behaviour depend on the variable type? What about if x,y are not ints but lists, strings or any other object?

It depends a lot on whether or not the values are mutable or immutable. Strings are immutable, so identical ones might have the same address. Lists are mutable, so it makes a big difference whether x and y refer to the same list or to two newly constructed lists. These two snippets are very different:

# These have different addresses. They can be changed independently.
x = []
y = []

# These variables refer to the same list.
x = []
y = x

Note that operators like += attempt to change the object in place. This is obviously not possible with immutable values, but for lists, y += [6] modifies the existing list, while y = y + [6] makes a new list. += is not always equivalent to plain addition.

luther
  • 5,195
  • 1
  • 14
  • 24