2011-06-15 150 views
1

可能重复:
Python list problem初始化矩阵在Python

我尝试初始化Python中的矩阵。 首先,我这样做:

>>> M=[[0]*4]*4 

但这里是我probleme,每行正在改变当我改变了第一个:

>>> M= [ [ 0 for i in range(4) ] for j in range(4) ] 

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]] 

所以我这样做了

而且ut工作正常:

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 

我的问题是:

这两个表达式的真正含义是什么?回答为什么第一个人会这样做?

在此先感谢您的帮助。

回答

1

a是一些python对象。然后[a] * 4相当于[a,a,a,a]。这意味着什么取决于a是否为可变或不。数字,字符串和元组不是,所以如果a是这些类型的对象之一(在您的示例0),那么你得到4个独立可变的副本。列表,字典和集合是可变的,在这种情况下,你只需要4个引用到同一个对象,在你的情况下,列表[0] * 4。利用这些知识,你会看到你可以做到这一点:

M = [[0] * 4 for i in range(4)] 

并得到你想要的。

2

因为这里M=[[0]*4]*4 您创建对象的链接。

这是类似

>>> a = [0, 0, 0] 
>>> b = [a,a,a] 
>>> b 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]] 
>>> a[1] = 1 
>>> b 
[[0, 1, 0], [0, 1, 0], [0, 1, 0]] 
>>> 

UPD链接我的意思是引用,对不起,如果有点混乱

3

当你乘这些名单,Python是通过引用复制它们,而不是创建全新的对象。

一个简单的例子可以帮助,展示了参照与复制发生:

>>> pie = ['apple', 'cherry', 'pecan'] 
>>> pie_copy = pie 
>>> pie_copy[0] = 'banana' 
>>> pie 
['banana', 'cherry', 'pecan'] 
>>> pie is pie_copy 
True 
>>> new_pie = ['banana', 'cherry', 'pecan'] 
>>> pie is new_pie 
False 

在这种pie_copy以同样的方式和饼形指向同一个列表,乘以建筑列表时,所有的副本指向相同的列表。

在你的第二个片段中,使用range()和列表解析,你没有一个单独的列表并复制它几次;理解中的每一次迭代都会创建一个新列表,所以您不会遇到相同的副本引用问题。