Strange 2 dimensional list behaviour in python
Why does python do the following?
>>> bla = [[]] * 5
>>> bla[3].append("blub")
>&g开发者_Go百科t;> print bla
[['blub'], ['blub'], ['blub'], ['blub'], ['blub']]
I would expect
[[], [], [], ['blub'], []]
This is a common point of confusion with Python, to do with the implicit pass-by-reference. When you type
x = []
that binds the name x
to point to an empty list in memory. When you do
x = [[]] * 5
that binds the name x
to point to a list of five things, each one of which is a reference to the same empty list. This might be clearer if you think of it like this:
>>> y = []
>>> x = [y]*5
>>> x
[[], [], [], [], []]
>>> x[0].append(0)
>>> x
[[0], [0], [0], [0], [0]]
>>> y
[0]
That is, even though []
doesn't bind any variable names, it still creates a reference to an empty list, which is then copied five times.
If you don't want this, you need explicitly to construct five empty lists to store in x
. There are various ways of doing this (copy.deepcopy
is a general solution), but I think the neatest is:
x = [[] for _ in range(5)]
Alternatively, numpy
is an extension module which provides a very powerful multidimensional array.
You're multiplying the contents of the original list five times - that inner list is just a reference, so the same reference is multiplied five times.
In other words, the final list you've got is a list containing the same list multiple times.
An easy way around this for Python 2:
[[] for i in xrange(5)]
Python 3:
[[] for i in range(5)]
精彩评论