在原始列表上的操作上更改列表的副本

时间:2013-06-30 12:07:14

标签: python object copy nested-lists

我正在编写一个片段来查找矩阵的行列式。矩阵表示为嵌套列表,如

[[2,3],[5,6]]

其中外部列表​​的成员是行,而内部列表的成员是列。

在必须通过删除一些元素将矩阵扩展为更简单的矩阵的步骤中,我必须将原始列表的备份保存到另一个列表'bak'以在后续扩展中使用它。

但是在第一次扩展步骤之后,当我尝试从'bak'恢复原始列表的值时,原始列表上的操作似乎也反映在'bak'上。

def determinant(matrix):
        if len(matrix)==2:
                det = matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1]
        if len(matrix)>2:
                flag=0
                bak=[]
                for x in matrix:
                        bak.append(x)
                dump=[]

                for ind,x in enumerate(matrix):
                        matrix.pop(ind)
                        for n,y in enumerate(matrix):
                                matrix[n].pop(ind)

                        dump.append(matrix)
                        print "bak",bak
                        matrix=bak

matrix=[[1,2,3],[4,5,6],[7,8,9]]
determinant(matrix)

在打印'bak'时,输出是[[1,2,3],[5,6],[8,9]],它应该是[[1,2,3],[4, 5,6],[7,8,9]]

如果我监督任何概念,请帮助我。

2 个答案:

答案 0 :(得分:4)

您只存储对原始列表的引用。您想要创建副本

bak.append(x[:])

bak.append(list(x))

[:]语法从原始列表的第一个元素到最后一个元素的切片创建一个新列表。

答案 1 :(得分:2)

(你似乎已经超越了自己的头脑。为什么你拥有所有这些全局变量?首先,在尝试做这样的事情之前,先了解函数如何正常工作。)

因为它不是真正的副本。 bak是来自matrix的单独列表,但它包含matrix所做的所有相同列表。

此外,每次通过外部循环,您将从matrix“恢复”bak ...但不是通过复制,只是别名它!因此,在循环的第二次,您最终让matrix命名为bak所列的相同列表,现在打败了预期的“备份”目的。

但是,对此的整个方法是错误的。 停止尝试“制作副本然后重复修改”,然后开始“反复修改版本”

退出尝试告诉Python如何将列表放在一起。它知道如何。

当我们将小任务分离到他们自己的函数中时,代码变得更加简单。首先,让我们创建一个函数,为我们提供一个列表,其中包含除指定元素之外的所有内容:

def all_except(a_list, index):
    return a_list[:index] + a_list[index + 1:]

这让我们可以轻松地创建一个函数,为我们提供一个矩阵,除了指定的行和列之外的所有内容 - 通过询问“没有指定列的行的副本,除了指定的行之外的每一行”:

def submatrix(matrix, r, c):
    return [all_except(row, c) for row in all_except(matrix, r)]
    # Alternatively:
    # return [all_except(row, c) for i, row in enumerate(matrix) if i != r]

现在我们可以实际进行递归。没有必要真正建立未成年人名单。

def determinant(matrix):
    if len(matrix) < 2: raise ValueError

    if len(matrix) == 2:
        return matrix[0][0] * matrix[1][1] - matrix[1][0] * matrix[0][1]

    return sum(
        column * (-1 ** r + c) * determinant(submatrix(matrix, r, c))
        for r, row in matrix
        for c, column in row
    )