Python列表问题
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]]
2 个回答
8
这有点复杂,但理解后就会觉得很简单。当你写 [[0]*3]*2
这段代码时,首先你是在创建一个包含三个零的列表,然后你把这个列表复制了一遍,变成了两个元素。但在复制的时候,你并没有创建两个新的列表,而是多次引用了同一个列表。所以当你修改其中一个列表时,所有的列表都会一起改变。
下面是一个例子来说明这个问题:
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]]
18
这是故意设计成这样的。当你对列表中的元素进行乘法运算时,其实是在复制这些元素的引用。
可以查看Python编程/列表的维基书中“列表创建快捷方式”这一部分,里面详细讲了关于可变对象的列表引用的问题。
他们推荐的解决办法是使用列表推导式:
>>> 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]]