在 python 中使用 a[:] 或 copy() 复制列表很浅? [复制]
Posted
技术标签:
【中文标题】在 python 中使用 a[:] 或 copy() 复制列表很浅? [复制]【英文标题】:Copying a list using a[:] or copy() in python is shallow? [duplicate] 【发布时间】:2016-12-14 23:26:10 【问题描述】:假设我有一个包含一些值的列表 a
,我做了一个 b = a[:]
。然后根据我阅读的内容修改列表b
的内容不会更改列表a
。所以,这意味着它是一个深拷贝。但是 python 文档仍然将此称为浅拷贝。有人可以为我清除这个吗?
【问题讨论】:
【参考方案1】:演示浅拷贝的含义:
a = [ [1,2], [3,4,5] ]
b = a[:] # make a shallow copy
a is b # not the same object, because this is a copy
=> False
a == b # same value, because this is a copy
=> True
a[0] is b[0] # elements are the *same objects*, because this is a *shallow* copy
=> True
改变a
的结构不会在b
中体现出来,因为这是一个副本:
a.pop()
len(a)
=> 1
len(b)
=> 2
为了演示与深拷贝的区别:就地更改包含在a
(与a
的结构相反)中的对象,反映在b
中,因为b
引用相同的对象作为a
。
a[0][0] = 'XYZ'
b[0]
=> ['XYZ', 2]
【讨论】:
所以这意味着浅拷贝只与复合对象相关,导致内部引用被拷贝。【参考方案2】:来自pythondocs
浅拷贝和深拷贝的区别只与 复合对象(包含其他对象的对象,如列表或 类实例):
浅拷贝构造一个新的复合对象,然后(到 尽可能)将引用插入其中找到的对象 原本的。深拷贝构造一个新的复合对象,然后, 递归地,将在其中找到的对象的副本插入其中 原创。
浅拷贝仅为顶层/对象创建一个新对象,然后通过引用复制所有子对象。深层复制为顶层对象/级别以及所有子对象创建新对象。
【讨论】:
【参考方案3】:然后修改列表“b”的内容不会改变列表“a”,正如我所读到的那样。
同理,如果你取出一些内容或将它们换成其他内容,它不会影响a
。 b
中保存的对象的突变将通过两个列表可见,因为两个列表都保存相同的对象。
>>> class Mutable(object):
... def __init__(self, x):
... self.x = x
... def __repr__(self):
... return 'Mutable()'.format(self.x)
...
>>> a = [Mutable(1), Mutable(2)]
>>> b = a[:]
>>> del b[1] # Doesn't affect a
>>> a
[Mutable(1), Mutable(2)]
>>> b[0].x = 5 # Visible through a
>>> a
[Mutable(5), Mutable(2)]
【讨论】:
【参考方案4】:然后修改列表“b”的内容不会改变列表“a”,正如我所读到的那样。所以,这意味着它是一个深拷贝。
不,它没有。浅拷贝与深拷贝的区别在于包含的值是否被拷贝。
在您的情况下,列表被复制,但两个结果列表将包含相同的对象。在一个列表中添加或删除值不会影响另一个列表,但会反映对包含对象的更改。
【讨论】:
以上是关于在 python 中使用 a[:] 或 copy() 复制列表很浅? [复制]的主要内容,如果未能解决你的问题,请参考以下文章