浅复制在python中不起作用

浅复制在python中不起作用,python,shallow-copy,Python,Shallow Copy,我试着做浅显的复制,但它不适合我 import copy a = [1,2,3,4] b = copy.copy(a) 现在a和b将具有相同的值[1,2,3,4]。但是如果我附加b.append(1),它不会反映在a中 b.append(1) print(b) [1,2,3,4,1] 但是在一个 print(a) [1,2,3,4] 有人能解释一下吗?浅拷贝就是这样做的。您的列表元素将是相同的,但列表本身将是不同的对象 如果要对同一列表进行其他引用,请执行以下操作: b = a 副本使存

我试着做浅显的复制,但它不适合我

import copy
a = [1,2,3,4]
b = copy.copy(a)
现在
a
b
将具有相同的值[1,2,3,4]。但是如果我附加
b.append(1)
,它不会反映在a中

b.append(1)
print(b)
[1,2,3,4,1]
但是在一个

print(a)
[1,2,3,4]

有人能解释一下吗?

浅拷贝就是这样做的。您的列表元素将是相同的,但列表本身将是不同的对象

如果要对同一列表进行其他引用,请执行以下操作:

b = a

副本使存储相同项的
A
b
列表对象不同:

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> a = [1,2,3,4]
>>> b = copy.copy(a)
>>> a is b
False
但是,浅层副本并不意味着列表内部的项目相同,例如:

>>> a = [object(), "foo", "bar"]
>>> b = copy.copy(a)
>>> a[0] is b[0]
True
>>> a[1] is b[1]
True
>>> import copy
>>> a = [{"name":"a"}, {"name":"b"}] 
>>> b = copy.copy(a)
>>> a[0]["age"] = 42
>>> a
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> b
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> a.append({"bar":"baaz"})
>>> a
[{'age': 42, 'name': 'a'}, {'name': 'b'}, {'bar': 'baaz'}]
>>> b
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> id(a)
139833628392264
>>> id(b)
139833599561240
>>> [id(x) for x in a]
[139833628091568, 139833599520392, 139833599544128]
>>> [id(x) for x in b]
[139833628091568, 139833599520392]
如果您想要的只是一个参考,您可以分配:

>>> a = [1,2,3,4]
>>> b = a
>>> a is b
True
>>> b.append(1)
>>> b
[1, 2, 3, 4, 1]
>>> a
[1, 2, 3, 4, 1]

第一件事:你得到的是预期的行为。“浅”复制意味着您创建了对象的新副本,因此添加到列表
b
显然不会影响列表
a

我只是想了解深度拷贝和浅拷贝的区别。因为shallowcopy和deepcopy的行为方式相同

在您的示例中,您正在执行包含不可变对象(整数)的可变容器(列表)的浅拷贝,因此结果实际上是相同的。要找出浅拷贝和深拷贝之间的区别,必须使用包含可变对象的列表-例如,dicts:

>>> a = [object(), "foo", "bar"]
>>> b = copy.copy(a)
>>> a[0] is b[0]
True
>>> a[1] is b[1]
True
>>> import copy
>>> a = [{"name":"a"}, {"name":"b"}] 
>>> b = copy.copy(a)
>>> a[0]["age"] = 42
>>> a
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> b
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> a.append({"bar":"baaz"})
>>> a
[{'age': 42, 'name': 'a'}, {'name': 'b'}, {'bar': 'baaz'}]
>>> b
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> id(a)
139833628392264
>>> id(b)
139833599561240
>>> [id(x) for x in a]
[139833628091568, 139833599520392, 139833599544128]
>>> [id(x) for x in b]
[139833628091568, 139833599520392]
如您所见,
a
b
是不同的对象-它们有不同的ID,添加到一个不会添加到另一个-但是它们(至少最初)共享相同的对象(就在副本
a[0]
a[1]
指向与
b[0]
b[1]
相同的对象之后)

现在,如果进行深度复制:

>>> c = copy.deepcopy(a)
>>> c
[{'age': 42, 'name': 'a'}, {'name': 'b'}, {'bar': 'baaz'}]
>>> [id(x) for x in c]
[139833599544408, 139833599594576, 139833599596256]
>>> c[0]["age"] = 84
>>> c
[{'age': 84, 'name': 'a'}, {'name': 'b'}, {'bar': 'baaz'}]
>>> a
[{'age': 42, 'name': 'a'}, {'name': 'b'}, {'bar': 'baaz'}]
>>> b
[{'age': 42, 'name': 'a'}, {'name': 'b'}]
>>> 
您可以看到
c
元素本身就是
a
元素的副本(不同的对象)


如果您真的想了解名称、对象和引用在Python中是如何工作的,这是一个很好的参考。

所以copy.copy()不用于浅层复制,因为它们都有不同的引用。不,不,对不起,我只是想了解deepcopy和浅层复制之间的区别。因为shallowcopy和deepcopy的行为方式相同。@Vivek,你的问题不是这样问的,那么deepcopy做什么呢。b=copy.deepcopy(a)For
[[x]]
->
copy.copy
为您提供一个具有相同
[x]
元素的新列表
copy.deepcopy
在一个新列表中为您提供
x
,它本身就在一个新列表中。如果您不想要单独的对象,为什么要复制一个副本?@Vivek当我读到
slice
操作创建一个浅层副本时,我的想法和您一样,但它的行为与我预期的不同。我用的是一个数字列表。我认为对于像整数这样的基本类型,浅拷贝和深拷贝并没有什么不同。它的行为方式与字符串相同,因为它们是不可变的。在对象的情况下,在浅拷贝和深拷贝之间进行实验更有意义。