正如我在课堂上所学到的,我理解浅拷贝和深拷贝的区别。然而,以下内容没有意义
import copy
a = [1, 2, 3, 4, 5]
b = copy.deepcopy(a)
print(a is b)
print(a[0] is b[0])
----------------------------
~Output~
>False
>True
----------------------------
当对象及其组成元素在深度副本的不同内存位置重新创建时,print(a[0] is b[0])
不应该计算为False吗?我只是在测试这个,因为我们在课堂上讨论过这个,但它似乎不起作用。
如果我们把这看作是一个机械问题,即
deepcopy
函数调用如何结束返回对相同int
对象的引用,而不是它们的副本,那么奥利维尔·梅隆的答案是正确的。我将后退一步,回答为什么这是deepcopy
要做的明智之举的问题。我们需要复制数据结构(深拷贝或浅拷贝)的原因是,我们可以在不影响原始状态的情况下修改它们的内容;或者,我们可以在保留旧状态副本的同时修改原始。当一个数据结构有自己可变的嵌套部分时,就需要一个深度拷贝。考虑这个例子,它将二维网格中的每个数字相乘,比如
[[1, 2], [3, 4]]
:列表之类的对象是可变的,因此操作
row[i] *= k
会更改它们的状态。复制列表是防止变异的一种方法;这里需要一个深度副本来复制外部列表和内部列表(即行),它们也是可变的。但整数和字符串等对象是不可变的,因此不能修改它们的状态。如果一个
int
对象是13,那么它将保持13,即使您将它乘以k
;乘法将产生一个不同的int
对象。没有变异可以防御,因此不需要复制。有趣的是,
deepcopy
如果元组的组件都是不可变的,则不会复制元组,但如果元组的组件是可变的,则会复制元组:其逻辑是相同的:如果一个对象是不可变的,但是有可变的嵌套组件,那么需要一个副本来避免对原始组件的变异。但是,如果整个结构是完全不可变的,就没有可以防御的突变,因此也就不需要拷贝。
在另一个答案中,有人认为这可能是因为Python为小整数保留了对象。虽然这种说法是正确的,但并不是导致这种行为的原因。
让我们看看当我们使用更大的整数时会发生什么。
如果深入研究} 的调用。
copy
模块,我们会发现使用原子值调用deepcopy
会延迟对函数^{所以实际发生的情况是
deepcopy
不会复制原子值,而只返回它。举个例子,这就是
int
、float
、str
、function
等等的情况。这种行为的原因是Python优化小整数,使它们实际上不在不同的内存位置。查看
1
的id
,它们总是相同的:来自Integer Objects的引用:
相关问题 更多 >
编程相关推荐