5
class Board:

    def __init__(self):
        self.board = self.createBoard()

    def createBoard(self):
        line = []
        for i in range(7):
            line.append(' ')
        board = []
        for i in range(7):
            board.append(line)
        return board

    def showBoard(self):
        line = "| "
        for x in range(len(self.board)):
            for y in range(len(self.board)):
                line += self.board[x][y] + " | "
            print("-" * 29)
            print(line)
            line = "| "
        print("-" * 29)

if __name__ == '__main__':
    board = Board()
    board.showBoard()
    board.board[1][1] = "O"
    board.showBoard()

当我遇到这个非常奇怪的问题时,我正在开发一个 connect-4 python 控制台演示/游戏。

上面代码的输出如下:

-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------

奇怪的是,我从未分配O到所有这些位置,我只将它分配到位置 [1][1]。

我曾期望输出是:

-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------
|   | O |   |   |   |   |   | 
-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------
|   |   |   |   |   |   |   | 
-----------------------------

我极有可能遗漏了一些明显而小的东西,但我一直在寻找和尝试一个多小时,但我真的找不到问题所在。

这不像我的 board.board 列表比任何其他二维列表都更奇怪。

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

(这是我得到的print(board.board)

将其复制并粘贴到 IDLE 中,我得到以下信息:

>>> a = [[' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ']]
>>> a[1][1] = "O"
[[' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', 'O', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ']]

这让我得到了正确的董事会价值。

我的代码中有什么明显错误以至于我错过了它?我很确定,当你们中的任何人找到一个我会羞愧地摇头的答案时,它可能就那么糟糕。

足够的自我羞辱,那么为什么我的代码board.board[1][1] = "O"将值“O”分配给 中的每一行board.board

将第一个 1 从 0-6 更改为任何其他数字也不会改变任何内容。这都一样。

4

2 回答 2

6

常见问题解答中对此进行了解释,如何创建多维列表

问题出在这部分代码中:

board = []
for i in range(7):
    board.append(line)

您正在创建一个包含 7 个对同一列表的引用的列表,line. 所以,当你修改一个时,其他的都会改变,因为它们是同一个列表。

解决方案是创建 7 个单独的列表,如下所示:

def createBoard(self):
    board = []
    for i in range(7):
        line = []
        for i in range(7):
            line.append(' ')
        board.append(line)
    return board

或者,更简单地说,制作原始列表的单独副本:

def createBoard(self):
    line = []
    for i in range(7):
        line.append(' ')
    board = []
    for i in range(7):
        board.append(line[:])
    return board

当我们这样做时,您可以通过使用列表推导来极大地简化它:

def createBoard(self):
    return [[' ' for j in range(7)] for i in range(7)]

或者,正如常见问题解答所建议的,您最好使用更智能的多维数组对象,例如 numpy 或 pandas 提供的对象:

def createBoard(self):
    return np.tile(' ', (7, 7))

缺点是您需要安装 numpy,因为标准库中没有任何东西可以像这样工作。但优点是您拥有处理数组的强大工具——<code>a[1, 1] 并不比 简单得多a[1][1],但a[:,1]访问第二列却比 . 简单得多[row[1] for row in a]

于 2013-09-06T23:20:33.237 回答
0

这是 python 使用引用的问题。CreateBoard第二部分

    for i in range(7):
        board.append(line)

将 7 个对同一个列表的引用放在外部列表中。所以你有一个相同列表的 7 个副本的列表。编辑这些子列表之一中的值实际上会更新所有子列表,因为它们引用相同的内存。

一种选择是使用 copy.deepcopy,或者为每一行显式创建一个新列表

import copy  # at the top of the file
for i in range( 7 ):
    board.append( copy.deepcopy( line ) )

或者

for i in range( 7 ):
    board.append( list(' ' * 7) )
于 2013-09-06T23:28:20.033 回答