Why does appending to one list also append to all other lists in my list of lists? [duplicate]
Suppose I do the following:
>>> l = [[]]*2
>>> l
[[], []]
>>> l[0].append(1)
>>> l
[[1], [1]]
Why does 1 get appended to both lists?
[[]]*2
is a list of two references to the same list. You are appending to it and then seeing it twice.
Because there is really only one list. Consider this:
>>> l = [[]]
>>> l2 = l*2
>>> l2[0] is l[0]
True
>>> l2[1] is l[0]
True
*2
performed on a list does not copy the list but return a list of length 2
filled with the same reference.
What you probably wanted was this:
>>> l = [[] for _ in xrange(2)]
As @Asterisk mentions in a comment, the same behaviour is exposed by all common collections. As a rule of thumb it is therefore best to only use multiplication on immutable types with value-semantics.
Showcasing the difference with memory layout:
listOfLists = [[]] * 3
listOfListsRange = [[] for i in range(0, 3)]
Here's how i initialize a list of lists. Rows vary slowest.
nrows = 3; ncols = 5
l_of_ls = [[0]*ncols for i in range(nrows )]
for rix, r in enumerate(l_of_ls):
for cix, c in enumerate(r):
print rix, cix, 'val = ',c
RESULT
0 0 val = 0
0 1 val = 0
0 2 val = 0
0 3 val = 0
0 4 val = 0
1 0 val = 0
1 1 val = 0
1 2 val = 0
1 3 val = 0
1 4 val = 0
2 0 val = 0
2 1 val = 0
2 2 val = 0
2 3 val = 0
2 4 val = 0
Also Worth Noting for Indexing Purposes
for rix in range(nrows):
for cix in range(ncols):
print l_of_ls[rix][cix],
print
RESULT
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
精彩评论