4

我正在尝试在 python 2.7 中构建一个 5x5 网格的游戏板,表示为二维列表。我尝试将其编写为board = [["O"]*cols]*rows(列和行已被声明为 5),但是当我尝试编辑索引处的值时,它会更改整行。例如

cols = 5
rows = 5
board = [["O"]*cols]*rows

这打印:

[['O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O']]

现在,当我尝试更改索引的值时,例如:

board[1][1] = "X"

它打印:

[['O', 'X', 'O', 'O', 'O'], ['O', 'X', 'O', 'O', 'O'], ['O', 'X', 'O', 'O', 'O'], ['O', 'X', 'O', 'O', 'O'], ['O', 'X', 'O', 'O', 'O']]

我只想更改第 1 列第 1 行的值。

我还尝试执行以下操作:

board = []
for i in xrange(5):
    board.append(["O"]*cols)

这个工作就像我想要的那样。我想了解的是有什么区别?

4

3 回答 3

5

如果您评估下面的表达式,您将看到它将在您的第一个示例中返回 True,而在另一个示例中返回 False。两个列表实际上都指向内存中的同一个列表。

board[0] is board[1]

如果您确实想要一个简短的版本来制作不同的新列表,那么这个版本也可以正常工作。

board = [["O"]*cols for y in range(rows)]
于 2012-10-03T12:52:39.553 回答
1

因为 Python 没有隐式复制东西的习惯。[x] * 5意思是“一列 5 件事,每件事都是 x”。如果你改变了一个,你就改变了它们,因为它们都是x- 而不是x.

当您使用 时.append(),您会强制复制,因为每次通过循环时,您都会从头开始创建要附加的值。

是的,["O"] * 5生成一个包含 5 件事情的列表,每件事情都是一样的"O"。但是,这实际上并不相关。没有有意义的“不同"O"”之类的东西,因为你不能改变"O"——不管你对一个变量 "O"做了什么,"O"它仍然是"O"

于 2012-10-03T13:56:00.710 回答
0

您的第一个表达式是创建指向单个列表对象的指针列表。因此,当您更新一个元素时,它会随处更改。

于 2012-10-03T12:48:52.953 回答