Consider the following example:
In [20]: a = [[1], [2], [3]] In [21]: b = a In [22]: x = a[1] In [23]: a Out[23]: [[1], [2], [3]] In [24]: b Out[24]: [[1], [2], [3]] In [25]: x Out[25]: [2] In [26]: a[1][0] = 4 In [27]: a Out[27]: [[1], [4], [3]] In [28]: b Out[28]: [[1], [4], [3]] In [29]: x Out[29]: [4]
The difference here is that when we practiced using a[1] , we did this by changing it, instead of saying a[1] to refer to a completely new thing.
In your case, when you told x to refer to what refers to a[1] , he took a link to a specific thing, regardless of what was in a[1] at that time, in your case a certain integer number.
Later, when you told a[1] to change, it changed. But what it was referring to did not cease to exist (because x still referred to it there).
By saying x = a[1] , you are not saying that x always refers to what a[1] refers to.
You say that x will refer to the fact that a[1] refers to this moment of assignment.
The same is true for b , just so that the βspecificβ thing that b talked about to refer to is a whole list that can change the content.
Another example:
a = [1, 2, 3,] b = a print a, b