创建不引用包含对象的列表副本

时间:2014-04-07 10:40:36

标签: python object

假设我有一个向量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的副本,甚至不会引用所有内部对象?

4 个答案:

答案 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)

使用copy.deepcopy

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,如其他答案所示。