尽管使用独立副本,原始列表也会发生变化

时间:2019-01-19 17:41:27

标签: python python-3.x matrix

我想遍历矩阵的所有元素(在我的代码中为列表的列表),并在被检查的元素满足特定条件时每次都创建该矩阵的独立副本。

每次创建副本时,我都想更改复制的矩阵中的一个元素(以便原始矩阵保持不变)。矩阵的每个副本都应有一个单独的名称。

之后,我要将复制的矩阵存储在列表中。

因此,例如:考虑原始矩阵是一个2x2矩阵,其中包含四个整数(假设数字1到4,如下面的代码所示)。现在,让我们遍历矩阵元素,并在每次检查元素大于3时创建矩阵的副本。因此,我们应该获得一个副本(因为只有一个元素,数字4大于3)。在此复制的矩阵中,我更改了一个元素(例如,假设数字10被添加到所检查的元素中)。然后,我将复制的矩阵存储在列表中。我的代码如下:

matrix = [[1,2],[3,4]]
new_copies = []
counter = 0

for i in range(0,2):
    for k in range(0,2):
        if matrix[i][k] > 3:
            exec("item%s = matrix[:]" % counter)
            exec("item%s[i][k] = matrix[i][k] + 10" % counter)
            exec("new_copies.append(item%s)" % counter)
            counter += 1

print(matrix)
print(new_copies)

如果运行此代码,您将看到复制的矩阵正确更改并且也存储在列表中。

但是原始矩阵也被更改。为什么?我只操作矩阵的复制版本,该复制版本应与原始版本无关,因为我遵循以下原则:

new_matrix = original_matrix[:]

1 个答案:

答案 0 :(得分:0)

为什么会发生

列表是mutable对象,这就是为什么即使通过执行matrix[:]创建新列表对象,子列表仍然指向相同的对象...

第一个解决方案

这是第一个解决方法:

matrix = [[1, 2], [3, 4]]
new_copies = []
counter = 0

for i in range(0, 2):
    sublist = matrix[i][:]

    for k in range(0, 2):
        if matrix[i][k] > 3:
            sublist[k] += 10
            counter += 1

    new_copies.append(sublist)

print(matrix)
print(new_copies)

或具有列表理解力

如果可能的话,您也可以使用list comprehension,在这种情况下为:

new_copies = [[(e + 10 if e > 3 else e) for e in l] for l in matrix]

这将给您与我以前的主张相同的结果

或带有可变对象

一个不错的解决方案是使用元组而不是列表,因为它们是不可变的对象。但是如果您必须在程序中修改矩阵,那将是不可能的。

或使用Deepcopy

您还可以使用副本库中的deepcopy方法...

你看到我来了...

我必须提醒,如果可能,应避免使用eval ...