在Python2.7中,为什么grid=[[[A";]*5]*5不同于grid=[]grid.append[…]
我正在尝试构建一个游戏板,它是Python2.7中的5x5网格,表示为二维列表。 我试着将它写成board=[[“O”]*cols]*rows(cols和rows已经声明为5),但当我试图编辑索引处的值时,它会更改整行。比如说在Python2.7中,为什么grid=[[[A";]*5]*5不同于grid=[]grid.append[…],python,list,python-2.7,append,python-2.x,Python,List,Python 2.7,Append,Python 2.x,我正在尝试构建一个游戏板,它是Python2.7中的5x5网格,表示为二维列表。 我试着将它写成board=[[“O”]*cols]*rows(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'], ['
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)
这一个像我想要的那样工作。我想了解的是区别是什么?您的第一个表达式是创建指向单个列表对象的指针列表。因此,当您更新一个元素时,它在任何地方都会发生更改。如果您计算下面的表达式,您将看到第一个示例返回True,而另一个示例返回False。两个列表实际上都指向内存中的同一个列表
board[0]是board[1]
如果您确实希望有一个简短的版本来创建不同的新列表,那么这个版本也可以正常工作
board = [["O"]*cols for y in range(rows)]
因为Python没有隐式复制东西的习惯
[x]*5
表示“一个由5个事物组成的列表,每个事物都是x
”。如果你改变一个,你就改变了它们,因为它们都是x
——而不是x
的副本
使用.append()
时,会强制复制,因为每次通过循环时,都会从头创建要追加的值
是的,
[“O”]*5
生成一个包含5个内容的列表,每个内容都是相同的“O”
。然而,这实际上并不相关;“一个不同的“O”
”这样的事情是没有意义的,因为您不能更改“O”
——无论您对名为“O”
的变量做什么,“O”
仍然是“O”请注意,在Python中列表是从0索引的。因此,第1行第1列将由board[0][0]
返回。顺便说一句,这不是2.x特定的:它一直是这样工作的,而且几乎可以肯定总是这样工作的。使用该函数可能也很有趣:print id(board[0]
和print id(board[1])