3

In Fluent Python, By Luciano Ramalho, Chapter 8, Copies Are Shallow by Default, there is an example:

>>> listOne = [3, [55, 44], (7, 8, 9)]
>>> listTwo = list(listOne)
>>> listTwo
[3, [55, 44], (7, 8, 9)]
>>> listTwo == listOne
True
>>> listTwo is listOne
False

The author suggests that we should run through this code using Online Python Tutor to see what is happening step by step.

I executed the first two lines using Online Python Tutor, and this is the screen shot I got:

enter image description here

What confuses me is:

All three elements from the each list, the immutable integer, the list and the tuple are actually the same, e.g.

listOne[0] is listTwo[0] #True
listOne[1] is listTwo[1] #True
listOne[2] is listTwo[2] #True

So why the graph shows two separate 3s at the beginning of their respective list?

Yu Zhang
  • 2,037
  • 6
  • 28
  • 42
  • 4
    Since I'm not the developer of that website I can't tell you why they do it that way, but there are some possible reasons: Since integers are immutable, it doesn't really matter if two integers are the same object or not. It makes sense to avoid drawing arrows to integers just because it reduces visual noise. In fact, whether two integers are the same object or not can even depend on the python interpreter you're using. Overall, it makes little sense for the website to show which integers are identical and which aren't. Always showing them inline is a good design decision. – Aran-Fey Oct 15 '19 at 08:29
  • Take note that this is purely about how Online Python Tutor decides to visualise this. The Python language specification makes no guarantee whatsoever how objects exist in memory. In specific, depending on the implementation *neither* lists nor integers will be full-fledged objects unless you use them as such. – MisterMiyagi Oct 15 '19 at 09:08

2 Answers2

3

The developers of OnlinePythonTutor made this decision, documented under Unsupported features, because this is not a guaranteed language feature, but instead is implementation specific:

Python

for strings and numbers, you can't rely on the behaviors of id() or is matching CPython on your computer; when teaching beginners, you shouldn't rely on these behaviors since they are implementation-specific optimizations. for details, see GitHub issues here and here and here

You can see from issue 255 the behaviour used to be different for integers, even outside the -5 to 256 range.

Community
  • 1
  • 1
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
-3

This is CPython optimization. This may not be in other Python implementations.

x = 256
x is 256 # True
x = 257
x is 257 # False
yllw
  • 173
  • 3
  • 5
    This has nothing to do with integer interning. The code creates a shallow copy of the list, so of course the 2nd list contains the exact same objects as the first list. No "new" integers are being created at any point. You could replace the `3` with literally anything else and `listOne[0] is listTwo[0]` would still evaluate to `True`. – Aran-Fey Oct 15 '19 at 08:32