附加值开始时列表评估不正确

时间:2018-11-05 15:22:50

标签: python list

我正在尝试确定2个相同的列表在分配新值时返回不同值的原因。如果我有一个列表,a, 当我断言a的值等于类变量matrix时,我返回true。当我更改每个列表amatrix中第一个元素的值时,列表不再相等。操纵列表matrix会导致与预期不同的结果吗?

class Matrix():
    def __init__(self, cells):
        self.cells: int = cells
        self.block: list = [] 
        self.matrix: list = []
        self.empty_block()
        self.create_matrix()

    # empty block
    def empty_block(self):
        self.block = [list(None for row in range(self.cells)) for col in range(self.cells)]

    # matrix of blocks
    def create_matrix(self):
        self.matrix = [list(self.block for row in range(self.cells)) for col in range(self.cells)]

    def insert(self, row, block, sub_column, sub_row, value):
        a = [[[[None, None], [None, None]], [[None, None], [None, None]]], [[[None, None], [None, None]], [[None, None], [None, None]]]]
        print(self.matrix == a)
        a[row][block][sub_column][sub_row] = value
        self.matrix[row][block][sub_column][sub_row] = value
        print(self.matrix == a)
        print(f"a: {a}")
        print(f"b: {self.matrix}")

from matrix import Matrix
matrix = Matrix(2)
matrix.insert(0,0,0,0,1)

结果是:

True
False
a: [[[[1, None], [None, None]], [[None, None], [None, None]]], [[[None, None], [None, None]], [[None, None], [None, None]]]]
b: [[[[1, None], [None, None]], [[1, None], [None, None]]], [[[1, None], [None, None]], [[1, None], [None, None]]]]

预期结果是:

结果是:

True
True
a: [[[[1, None], [None, None]], [[None, None], [None, None]]], [[[None, None], [None, None]], [[None, None], [None, None]]]]
b: [[[[1, None], [None, None]], [[None, None], [None, None]]], [[[None, None], [None, None]], [[None, None], [None, None]]]]

1 个答案:

答案 0 :(得分:2)

这是a much more common list indexing error的一个令人费解的版本。在您的情况下,这有点微妙,因为您在一个地方创建了内部数组,然后在另一个地方复制了它。复制的列表为self.block,并在self.empty_block()中实例化,并且在您调用self.matrix时复制到self.create_matrix()中。我将您引向另一个问题,以了解为什么这会产生您看到的结果,但是解决方案基本上是您需要为矩阵中的每一行实例化一个新的“块”,或者您需要为该块创建该块的副本。每一行。如果仅通过列出一堆相同块的列表来简单地创建矩阵,则实际上只有两个数组,即矩阵和一个块,该数组在矩阵中指向多次。像下面这样的东西应该适合您:

# empty block
def create_empty_block(self):
    return [list(None for row in range(self.cells)) for col in range(self.cells)]

# matrix of blocks
def create_matrix(self):
    self.matrix = [list(self.create_empty_block() for row in range(self.cells)) for col in range(self.cells)]