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?
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
.
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)]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With