In this particular example, inner.append (and outer[0].append, which is the same thing) appears to change everything in outer because outer contains 4 distinct references to inner, not 4 distinct list objects.
Hi.
I think I got an answer-like thing for the (same) question that I tried to report or ask.
It is weird because when I run the codes listed below, it worked as I thought.
What is the difference between the first and the second?
li = [[ ]]*3
li[1].append(1)
li
[[1], [1], [1]]
li = [[1], [2], [3]]
li[1].append(1)
li
[[1], [2, 1], [3]]
Anyway, it is not a bug, so I should use different codes to work properly.
This is not strange behaviour of append, it is “strange” (but not
really!) behaviour of *, list replication.
Here is an example:
a = [] # Create one list.
b = [a, a, a] # Repeat the same list three times.
a.append(99)
print(b)
What do you expect to happen? I hope you can see that you should get:
[[99], [99], [99]]
because the list a is repeated three times in the list b.
When you write:
[x]*3
Python does not make three copies of x. It just repeats it three
times, like:
[x, x, x]
but they are not copies! They are the same x. For immutable objects
like numbers and strings, the difference between a copy and a
replication doesn’t matter, because you cannot change the object, you
can only replace it with a new object.
b = [1]*3 # repeat the same object 1 three times
b[0] += 100 # replaces the 1 in position 0 with 101
print(b) # prints [101, 1, 1]
But with lists, they are mutable objects, so if you change the list in
position 0, you also change the other lists, since they are the same
list.