Python Forum

Full Version: Strange behavior list of list
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
You can initialise a list containing 3 zeroes as follows:
mylist = 3*[0]

If you initialise a list containing 4 of such lists as follows:
mylist = 4*[3*[0]]

you get the following list of lists:
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

Now try to assign a value to the first element of the first list as follows:
mylist[0][0] = 1

When you print mylist you get:
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]

Why is the value duplicatied 4 times?
I don't understand this.

If you define exactiy the same list by writing it out:
mylist2 = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

mylist2 looks the same as mylist initially. But now you can assign elements without the duplication.

It seems as if Pyhon creates a list of three items under water and creates the outer list as 4 references to this list.
Is there a way to avoid this without having to spell things out?
This makes a list that contains three zeros. All the zeros are the same object.
mylist = 3*[0]
This makes a list of four lists. All the interior lists are the same object.
mylist = 4*[3*[0]]
It is exactly the same as if you did this.
zeros = 3 * [0]
mylist = 4 * [zeros] 
An easy way to avoid this is:
mylist = [3 * [0] for _ in range(4)]
"3 x [0]" is called 4 times, adding the result to mylist. This is a list comprehension, a kind of shorthand way of writing this:
mylist = []
for _ in range(4):
    mylist.append(3 * [0])
Here are two diagrams showing the internal structure of mylist and mylist2. As you can see, mylist contains 4 references to a single sublist while mylist2 contains 4 references to 4 independent sublist. (these pictures were produced by the educational module swampy.Lumpy showing live Python objects)
Thanks to both of you. Makes sense.