在修改 Python 中的内容时迭代二维列表

Iterating over a 2D list while modifying the contents in Python

我正在为我正在进行的项目编写一个函数,该函数应该获取对象的二维列表并对其进行编辑。我正在使用嵌套的 for 循环,就像这样

class Thing:
    def __init__(self, x = 0, y = 0, sound = '...'):
        self.x = x
        self.y = y
        self.sound = sound

def change_list(to_change):
    for i in range(len(to_change)):
        for j in range(len(to_change[i])):
            to_change[i][j] = Thing(i, j, "Meow")
    return to_change

mylist = [[Thing()] * 1000] * 800
mylist = change_list(mylist)
print(mylist[1][1].x)
print(mylist[1][0].y)

我希望上面的代码输出 1,然而,它输出 799。 该代码似乎可以很好地分配 y 值。有人能帮帮我吗?

谢谢!

这可能与您认为的不同:

mylist = [[Thing()] * 1000] * 800

它创建了一个 Thing(),将其放入一个列表中,然后将其组合成一个列表,其中包含相同的内容 1000 次。然后它获取该列表,并创建另一个包含第一个列表 800 次的列表。

毕竟 - 仍然只有 1 个实际 Thing。试试这个:

mylist = [[Thing()] * 2] * 2
mylist[0][0].x = 42
print(mylist[0][1], mylist[1][0], mylist[1][1])  # 42 42 42

如果您想要 800 个列表,每个列表包含 1000 个事物,所有 800,000 个事物分开,您可以这样做:

mylist = [[Thing() for _ in range(1000)] for _ in range(800)]

这在 800 个单独的列表中分别创建了 1000 次。但是,none 确实很重要,因为在调用 change_list 时,您正在用新事物替换所有以前的事物。或者至少,如果您按照前面示例中描述的方式创建它,您会是。

如果这就是您正在做的,您不妨重新生成整个列表:

def create_list(rows, cols):
    return [[Thing(col, row) for row in range(rows)] for col in range(cols)]

如果您只想更改已经存在的内容(例如,只是更新现有内容的 xy

def change_list(to_change):
    for ncol, col in enumerate(to_change):
        for nrow, thing in enumerate(col):
            thing.x = ncol
            thing.y = nrow
            thing.sound = 'Meow'

您不需要访问长度,您可以循环遍历某物的内容并使用 enumerate() 如果您还需要该物的相对位置(索引)。