我对浅拷贝的工作原理有些困惑,我的理解是当我们执行 new_obj = copy.copy(mutable_obj)
时,会创建一个新对象,其中的元素仍指向旧对象。
以下是我感到困惑的例子 -
## assignment
i = [1, 2, 3]
j = i
id(i[0]) == id (j[0]) # True
i[0] = 10
i # [10, 2, 3]
j # [10, 2, 3]
## shallow copy
k = copy.copy(i)
k # [10, 2, 3]
id(i) == id(k) # False (as these are two separate objects)
id(i[0]) == id (k[0]) # True (as the reference the same location, right?)
i[0] = 100
id(i[0]) == id (k[0]) # False (why did that value in that loc change?)
id(i[:]) == id (k[:]) # True (why is this still true if an element just changed?)
i # [100, 2, 3]
k # [10, 2, 3]
在浅拷贝中,
k[0]
不就像赋值一样指向 i[0]
吗?那么当 i[0]
改变时,k[0]
不应该也跟着改变吗?我为什么期望它们相同呢?因为 -
i = [1, 2, [3]]
k = copy(i)
i # [1, 2, [3]]
k # [1, 2, [3]]
i[2].append(4)
i # [1, 2, [3, 4]]
k # [1, 2, [3, 4]]
id(i[0]) == id (k[0]) # True
id(i[2]) == id (k[2]) # True
id(i[:]) == id (k[:]) # True
int
是不可变对象,因此您需要在i[0]
上设置一个新对象。 - Willem Van Onsemi[0]
仍然指向k[0]
?这两个列表是不同的,因此一个列表中的更新不会反映到另一个列表中。 - Willem Van Onsemid(i[:]) == id (k[:])
为True(即使k有一个新元素)吗? - Ani Menonid(i[:]) == id(k[:]) # True(如果一个元素刚刚改变,为什么这仍然是真的?)
。这可能是CPython实现的细节。对于列表来说,id
基于内存地址,这个地址很可能被重复使用,因为i[:]
立即被垃圾回收了。这两个列表不是同一个对象。 - Håken Lid