二维列表在python中错误地赋值 [英] Two-dimensional list wrongly assigning values in python

查看:27
本文介绍了二维列表在python中错误地赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类板:def __init__(self):self.board = self.createBoard()def createBoard(self):行 = []对于范围内的 i (7):line.append(' ')板 = []对于范围内的 i (7):board.append(行)返回板def showBoard(self):行 = "| "对于范围内的 x(len(self.board)):对于范围内的 y(len(self.board)):line += self.board[x][y] + " | "打印(-"* 29)打印(行)行 = "| "打印(-"* 29)如果 __name__ == '__main__':板 = 板()board.showBoard()board.board[1][1] = "O"board.showBoard()

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

上面代码的输出如下:

-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------||哦||||||-----------------------------

奇怪的是,我从来没有将 O 分配给所有这些位置,我只将它分配给位置 [1][1].

我原以为输出是:

-----------------------------||||||||-----------------------------||哦||||||-----------------------------||||||||-----------------------------||||||||-----------------------------||||||||-----------------------------||||||||-----------------------------||||||||-----------------------------

我极有可能遗漏了一些明显而小的东西,但我已经寻找并尝试了一个多小时,但我真的找不到问题.

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

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

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

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

<预><代码>>>>a = [['','','','','','',''],['','','','','','',''],[' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', '','','','','',''],['','','','','','',''],['','',''', ' ', ' ', ' ', ' ']]>>>a[1][1] = "O"[[' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', 'O', ' ', ' ', ' ', ' ', ' '], ['', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ',' ', ' ', ' ', ' ']]

这让我获得了正确的董事会价值.

我的代码有什么明显错误以至于我遗漏了它?我敢肯定,当你们中的任何人找到一个让我羞愧地摇头的答案时,情况很可能很糟糕.

足够自欺欺人了,那么为什么我的代码 board.board[1][1] = "O" 将值O"分配给 board 中的每一行.板?

将第一个 1 更改为 0-6 之间的任何其他数字也不会改变任何内容.都是一样的.

解决方案

这在 FAQ 中有解释,位于 如何创建多维列表?

问题出在这部分代码:

board = []对于范围内的 i (7):board.append(行)

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

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

def createBoard(self):板 = []对于范围内的 i (7):行 = []对于范围内的 i (7):line.append(' ')board.append(行)返回板

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

def createBoard(self):行 = []对于范围内的 i (7):line.append(' ')板 = []对于范围内的 i (7):board.append(line[:])返回板

<小时>

虽然我们正在这样做,但您可以通过使用列表推导式来极大地简化:

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

<小时>

或者,正如 FAQ 所建议的那样,您最好使用更智能的多维数组对象,例如 numpy 或 pandas 提供的对象:

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

缺点是你需要安装numpy,因为标准库中没有这样的东西.但好处是你拥有处理数组的强大工具——a[1, 1] 并不比 a[1][1] 简单多少,但是 a[:,1] 访问第二列比 [row[1] for row in a] 要简单得多.

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()

I was working on a connect-4 python console demo/game when I got stuck on this really weird issue.

The output of the code above is as follows:

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

The weird thing is, I never assigned O to all those positions, I only assigned it to the position [1][1].

I had expected the output to be:

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

It is extremely likely that I'm missing something obvious and small but I've been looking and trying for over an hour and I really can't find the problem.

It's not like my board.board list is any more odd than any other two-dimensional list.

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

(It's what I get when I print(board.board))

Copying and pasting that into IDLE I get the following:

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

Which gets me the proper board value.

What is so obviously wrong in my code that I'm missing it? I'm pretty sure that when any of you find an answer that I'll shake my head in shame, it's likely that bad.

Enough self-shaming, so why does my code board.board[1][1] = "O" assign the value "O" to the every single row in board.board?

Changing the first 1 to any other number from 0-6 doesn't change anything either. It's all the same.

解决方案

This is explained in the FAQ, under How do I create a multidimensional list?

The problem is in this part of the code:

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

You're creating a list with 7 references to the same list, line. So, when you modify one, the others all change, because they're the same list.

The solution is to create 7 separate lists, like this:

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

Or, more simply, make separate copies of the original list:

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


While we're at it, you could simplify this tremendously by using list comprehensions:

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


Or, as the FAQ suggests, you might do better to use a smarter multidimensional array object, like the ones numpy or pandas provide:

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

The disadvantage is that you will need to install numpy, because there's nothing in the standard library that works like this. But the advantage is that you have powerful tools for dealing with arrays—a[1, 1] isn't much simpler than a[1][1], but a[:,1] to access the second column is a lot simpler than [row[1] for row in a].

这篇关于二维列表在python中错误地赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆