【发布时间】:2016-12-14 23:26:10
【问题描述】:
假设我有一个包含一些值的列表 a,我做了一个 b = a[:]。然后根据我阅读的内容修改列表b 的内容不会更改列表a。所以,这意味着它是一个深拷贝。但是 python 文档仍然将此称为浅拷贝。有人可以为我清除这个吗?
【问题讨论】:
标签: python python-3.x
假设我有一个包含一些值的列表 a,我做了一个 b = a[:]。然后根据我阅读的内容修改列表b 的内容不会更改列表a。所以,这意味着它是一个深拷贝。但是 python 文档仍然将此称为浅拷贝。有人可以为我清除这个吗?
【问题讨论】:
标签: python python-3.x
演示浅拷贝的含义:
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]
【讨论】:
来自pythondocs
浅拷贝和深拷贝的区别只与 复合对象(包含其他对象的对象,如列表或 类实例):
浅拷贝构造一个新的复合对象,然后(到 尽可能)将引用插入其中找到的对象 原本的。深拷贝构造一个新的复合对象,然后, 递归地,将在其中找到的对象的副本插入其中 原创。
浅拷贝仅为顶层/对象创建一个新对象,然后通过引用复制所有子对象。深层复制为顶层对象/级别以及所有子对象创建新对象。
【讨论】:
然后修改列表“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)]
【讨论】:
然后修改列表“b”的内容不会改变列表“a”,正如我所读到的那样。所以,这意味着它是一个深拷贝。
不,它没有。浅拷贝与深拷贝的区别在于包含的值是否被拷贝。
在您的情况下,列表被复制,但两个结果列表将包含相同的对象。在一个列表中添加或删除值不会影响另一个列表,但会反映对包含对象的更改。
【讨论】: