首页 > 解决方案 > python中列表的深拷贝

问题描述

PYCHARM 中的代码

[1]:https://i.stack.imgur.com/aBP1r.png

我试图制作列表 l 的深层副本,但似乎切片方法不起作用?我不希望 x 中的更改反映在 l 中。那么我应该如何进行深层复制以及我的代码有什么问题?

这是我的代码-

def processed(matrix,r,i):
    matrix[r].append(i)
    return matrix

l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x=l[:]
print(processed(x,0,10))
print(l)

输出-

[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]
[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]

标签: pythonpython-3.xlist

解决方案


您的代码确实成功地创建了浅拷贝。这可以通过检查两个外部列表的 ID 并注意它们的不同来看出。

>>> id(l)
140505607684808

>>> id(x)
140505607684680

或者简单地比较使用is

>>> x is l
False

但是,由于是浅拷贝而不是深拷贝,因此列表的对应元素彼此是同一个对象:

>>> x[0] is l[0]
True

这为您提供了在附加子列表时观察到的行为。

如果实际上您想要的是深层副本,那么您可以使用copy.deepcopy. 在这种情况下,子列表也是新对象,可以附加到而不影响原始对象。

>>> from copy import deepcopy

>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>>> xdeep = deepcopy(l)

>>> xdeep == l
True

>>> xdeep is l
False     <==== A shallow copy does the same here

>>> xdeep[0] is l[0]
False     <==== But THIS is different from with a shallow copy

>>> xdeep[0].append(10)

>>> print(l)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>>> print(xdeep)
[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]

如果你想在你的函数中应用它,你可以这样做:

from copy import deepcopy

def processed(matrix,r,i):
    new_matrix = deepcopy(matrix)
    new_matrix[r].append(i)
    return new_matrix

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x = processed(l,0,10)
print(x)
print(l)

如果事实上你知道矩阵总是正好 2 深,那么你可以比使用更有效地做到这一点deepcopy并且不需要import

def processed(matrix,r,i):
    new_matrix = [sublist[:] for sublist in matrix]
    new_matrix[r].append(i)
    return new_matrix

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
x = processed(l,0,10)
print(x)
print(l)

推荐阅读