2009-12-24 77 views
10

蟒蛇:Python列表問題

m=[[0]*3]*2 
for i in range(3): 
    m[0][i]=1 

print m 

我希望這個代碼應打印

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

但它打印

[[1, 1, 1], [1, 1, 1]] 

回答

14

這是由設計。當您在列表的元素上使用乘法時,您正在重現參考。

請參閱the section "List creation shortcuts" on the Python Programming/Lists wikibook,其中詳細介紹了有關可變對象的列表引用的問題。

他們建議的解決方法是一個列表理解:

>>> s = [[0]*3 for i in range(2)] 
>>> s 
[[0, 0, 0], [0, 0, 0]] 
>>> s[0][1] = 1 
>>> s 
[[0, 1, 0], [0, 0, 0]] 
6

這有點魔鬼,但很明顯,當你知道自己在做什麼。當你在做[[0]*3]*2位時,你首先創建一個有3個零的列表,然後複製這個列表來創建兩個元素。但是當你做這個副本時,你不會創建具有相同內容的新列表,而是多次引用相同的列表。所以當你改變它時,它們都會改變。

一個例子來突出它:

In [49]: s = [[]]*2 # Create two empty lists 

In [50]: s # See: 
Out[50]: [[], []] 

In [51]: s[0].append(2) # Alter the first element (or so we think) 

In [52]: s # OH MY, they both changed! (because they're the same list!) 
Out[52]: [[2], [2]]