尝试创建和更改网格,但将值分配给嵌套列表中的特定索引意外地复制到其他嵌套列表

Trying to create and alter grid, but assigning values to specific index in nested list is unexpectedly duplicated to other nested lists

(Python 3.9) 我正在尝试解决渗滤问题 problem/assignment,只是为了开始,我正在创建一个 n×n 网格。虽然网格在创建时看起来是正确的,但当我尝试更改网格内的特定值(在嵌套列表中)时,它会将该值分配给每个子列表,而不仅仅是我用它的索引引用的列表。

这是 class 和相关位:

class Percolation:
    """Create an n-by-n grid, with all sites initially blocked."""
    def __init__(self, n):
        self.grid = self.create_grid(n)

    def create_grid(self, n):
        """ Create n-by-n grid with default 0 (blocked) values."""
        grid = []
        # Create x, rows.
        values = [0 for _ in range(n)]
        # Create y, columns.
        for _ in range(n):
            grid.append(values)
        return grid

    def show_grid(self):
        for row in self.grid:
            print(row)

size = 5
perc = Percolation(size)
# I chose 8 and 5 arbitrarily to test this issue so they're easy to spot.
perc.grid[0][2] = 8
perc.grid[1][1] = 5
perc.show_grid()

show_grid() 然后显示所有子列表都已更改。

>>> 
[0, 5, 8, 0, 0]
[0, 5, 8, 0, 0]
[0, 5, 8, 0, 0]
[0, 5, 8, 0, 0]
[0, 5, 8, 0, 0]

虽然我期待的是:

>>> 
[0, 0, 8, 0, 0]
[0, 5, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]

我通过在循环中多次附加“值”来创建网格时是否犯了错误?还是我错误地引用了索引?我想也许起初 show_grid() 不小心一遍又一遍地打印同一行,但是直接打印 self.grid 仍然会在所有子列表中显示重复值,无论 n 或我如何分配值。

我看到的是,当我只更改主列表中的一个值时,我确实得到了我期望的结果。

perc.grid[2] = [0, 0, 8, 0, 0]
perc.show_grid()

>>>
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 8, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]

在这种情况下,如何正确更改这些嵌套列表中的值?当我设置 perc.grid[0][2] = 8?

时实际发生了什么

在python中创建列表并将其分配到多个位置时,它是同一个列表,而不是具有相同值的新列表。因此,当您创建列表 values 并将其附加到 grid 时,每个嵌套列表实际上是相同的列表。

避免此问题的一种方法是使用整个列表的索引复制列表 [:],例如: grid.append(values[:])