为什么整数列表的深度复制会在内存中返回相同的整数?

Ger*_*Lee 16 python deep-copy python-3.x

我理解浅层复制和深层复制之间的区别,就像我在课堂上学到的那样.但是以下没有意义

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
----------------------------
Run Code Online (Sandbox Code Playgroud)

print(a[0] is b[0])由于在深层副本中的不同内存位置重新创建对象及其组成元素,因此不应评估为False?我正在测试这个,因为我们已经在课堂上讨论了它,但它似乎没有用.

Oli*_*çon 15

余浩的回答其实并不正确.虽然Python确实为小整数实例化了对象,但并不是导致这种行为的原因.

让我们来看看当我们使用更大的整数时会发生什么.

> from copy import deepcopy
> x = 1000
> x is deepcopy(x)
True
Run Code Online (Sandbox Code Playgroud)

如果我们深入了解copy模块,我们发现deepcopy使用原子值调用会延迟对函数的调用_deepcopy_atomic.

def _deepcopy_atomic(x, memo):
    return x
Run Code Online (Sandbox Code Playgroud)

所以实际发生的是deepcopy不会复制不可变值,而只返回它.

举例这是时int,float,str,function等等.

  • 好答案; +1。我认为值得注意的是,“deepcopy”确实会复制非原子不可变值,例如元组,如果它们具有可变组件,例如“([1, 2], [3, 4])”。 (2认同)

Yu *_*Hao 11

这种行为的原因是Python优化了小整数,因此它们实际上并不在不同的内存位置.退房id1,他们总是相同的:

>>> x = 1
>>> y = 1
>>> id(x)
1353557072
>>> id(y)
1353557072

>>> a = [1, 2, 3, 4, 5]
>>> id(a[0])
1353557072

>>> import copy
>>> b = copy.deepcopy(a)
>>> id(b[0])
1353557072
Run Code Online (Sandbox Code Playgroud)

整数对象的引用:

当前实现保持整数对象对之间的所有整数数组-5256,当您创建在该范围内的int你其实只是回到现有对象的引用.所以应该可以改变它的值1.我怀疑在这种情况下Python的行为是未定义的.:-)

  • 这似乎不是原因;对于未缓存的较大数字或字符串,可以观察到相同的行为。 (2认同)