Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python list confusion [duplicate]

Tags:

python

list

Let's say I have the following code:

a_list = [[0]*10]*10

This generates the following list:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

Then I want to modify the first element in the first list:

a_list[0][0] = 23

I expected only the first element of the list to be modified, but actually the first element of each list was changed:

[[23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [23, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

I managed to find another way to represent my data to avoid this but why is this happening? Why isn't just the first list changed? When I do the second *10, does Python actually copy the first list's address instead of allocating a new memory block?

like image 815
Virgiliu Avatar asked May 10 '11 22:05

Virgiliu


2 Answers

Your hunch about copying addresses is correct. Think about it like this:

sub_list = [0] * 10
a_list = [sub_list] * 10

This code is actually equivalent to the code you have posted above. What this means is that you are actually changing the same list sub_list whenever you change any element of a_list. You can even make sure of it by typing:

a_list = [[0] * 10] * 10
for n in a_list:
    print id(n)

And it will show up the same for every element. To remedy this, you should use:

a_list = [[0] * 10 for _ in range(10)]

In order to create a new sublist for every element of a_list.

like image 178
146 Avatar answered Nov 20 '22 02:11

146


Lists contain references to objects. Multiplication on lists simply repeats the references (to the same objects!). While this is fine for immutable objects (like integers), what you are getting is multiple references to the same list.

Create separate lists with this pattern [[0]*10 for _ in xrange(10)].

like image 4
Mark Tolonen Avatar answered Nov 20 '22 02:11

Mark Tolonen