Your list1.append(list1[0])
line appends an alias of the 0-th element, which is a list object, of list1
to itself. Now list1
looks like this in memory:
[1] <-----+
^ |
| |
[index 0, index 1]
That is, there are two references to the same inner list at both index 0 and 1.
Then, list1[1].append(2)
pushes 2 to this single list, making it:
[1,2] <---+
^ |
| |
[index 0, index 1]
Finally, you add another reference to this whole structure: list2 = list1
.
The result looks like:
[1,2] <---+
^ |
| |
list1: [index 0, index 1]
^
|
list2
You've only created a total of one inner list and one outer list. Modifications done to list2
will affect list1
, and modifications on either index of either reference list will affect both indexes of both references.
While the example you've provided is a bit contrived and the use case is unclear (you may not actually want to copy these lists, especially if they are complex objects, and it's not clear whether it's indended that list2
alias list1
), you probably want something like:
list1 = [[1]]
list1.append(list1[0][:]) # copy using slice syntax
list1[1].append(2)
list2 = [x[:] for x in list1] # copy again using slice syntax and a list
# comprehension, assuming you don't want an alias