假设我有一个向量a
定义为:
a = [[1,2,3],[-1,-2,-3]]
我已经了解到要创建对象a
的副本而不引用它,我应该使用以下语法:
b = a[:]
的确,如果我执行以下语句:
b = []
print a
输出
>>> [[1,2,3],[-1,-2,-3]]
完全按照我的预期。但是,如果我执行以下操作:
b = a[:]
b[0][2] = 'change a'
print a
输出
>>> [[1,2,'change a'],[-1,-2,-3]]
所以我很清楚即使a[0]
中包含对象a
也被引用了。如何创建对象a
的副本,甚至不会引用所有内部对象?
答案 0 :(得分:5)
a[:]
创建列表的浅副本。
您可以使用copy.deepcopy()
function递归复制对象,或使用列表解析:
b = [el[:] for el in a]
这将创建一个新的列表对象,其中包含a
中嵌套列表对象的浅层副本。
答案 1 :(得分:4)
使用deepcopy
:
>>> from copy import deepcopy
>>> b = deepcopy(a)
>>> b[0][2] = 'change a'
>>> print a
[[1,2,3],[-1,-2,-3]]
Deepcopy:https://docs.python.org/2/library/copy.html#copy.deepcopy
Deepcopy还会创建一个类实例的单独副本。请参阅下面的简单示例。
from copy import deepcopy
class A:
def __init__(self):
self.val = 'A'
>>> a = A()
>>> b = deepcopy(a)
>>> b.val = 'B'
>>> print a.val
'A'
>>> print b.val
'B'
答案 2 :(得分:4)
import copy
b = copy.deepcopy(a)
引用文档:
深层复制构造一个新的复合对象,然后递归地, 将副本插入原始
中找到的对象
示例:
>>> a = list(range(1000))
>>> b = copy.deepcopy(a)
>>> a is b # b is a new object
False
>>>
答案 3 :(得分:4)
如果您只是“浅拷贝”b = a[:]
,则每个子列表b[n]
仍然是对a[n]
引用的同一子列表的引用。相反,你需要做一个深度(呃)副本,例如由
b = [l[:] for l in a]
这会创建每个子列表的浅表副本,但由于它们的内容是不可变的,因此不是问题。如果您有更多级别的容器嵌套,则需要copy.deepcopy
,如其他答案所示。