Python列表问题

11 投票
2 回答
4492 浏览
提问于 2025-04-15 17:21

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]]

撰写回答