Skip to main content
 首页 » 编程设计

python之无法理解浅拷贝

2025年05月04日10lyhabc

>>> a = [1,2,3] 
>>> b = a[:] 
>>> id(a[0]) == id(b[0]) 
True 
>>> b[0] = 99 
>>> id(a[0]) == id(b[0]) 
False 

我知道要制作浅拷贝,我们可以使用切片,而且还有一个复制模块。但是为什么写入“b”的索引会改变 id。

请您参考如下方法:

第 1 部分:为什么调用 b[0] = 99原因a[0] == b[0] >> False ?

您的问题的答案是,当您执行 b[0] = 99 时,您不会“修改 B 的一个字段指向的内存地址”,您实际上更改了 B 的一个字段指向的位置。

a = [1,2,3]   

现在a包含对 list 的引用对象,它又包含对三个 int 的三个引用对象。

b = a[:] 

现在 b 指的是 list对象(与 a 所指的对象不同),并且包含对三个 int 的三个引用对象,与 a 相同的对象指的是。

id(a) == id(b) 
#False 

错误,因为 a和 b是对不同 list 的引用对象。

id(a[0]) == id(b[0]) 
#True 

是的,因为 a[0]是对 1 的引用对象,b[0] 也是.只有一个 1对象,它由 a[0] 引用和 b[0]

b[0] = 99   
# ^^^^^^ THIS IS NOT WHAT THE WIKIPEDIA ARTICLE IS DESCRIBING 

b仍然指代相同的旧list对象,但是 b[0]现在指的是99目的。您只是替换了 list 中的引用之一。由 b 提及对不同对象的新引用。您未修改任何 a 的对象指向!

id(a[0]) == id(b[0])  
#False 

错误,因为 1对象与 99 不是同一个对象对象。


第 2 部分:那篇维基百科文章到底在说什么?

下面是一个复制操作的例子,你实际上是在“修改 B 的一个字段指向的内存地址”,所以你可以看到复制对象的后续变化。

a = [[1],[2],[3]] 

a是对 list 的引用对象,但现在 list对象包含对 list 的三个引用对象,每个对象都包含对 int 的引用对象。

b = a[:] 

和以前一样,你已经制作了b引用一个新的,不同的 list对象,指的是相同的三个 list a 中提到的对象.证明如下:

id(a) == id(b) 
# False 

错误,因为和以前一样a和 b是对不同 list 的引用对象。

id(a[0]) == id(b[0])  
#True 

没错,因为和以前一样,a[0]和 b[0]引用同一个对象。这次是 list对象,它不是不可变的,不像 int对象 - 我们实际上可以更改 list 的内容目的! 这里是它的不同之处:

b[0][0] = 99   

我们做到了 - 我们更改了 list 的内容 b[0] 引用的对象

a[0][0] 
# 99 !!!!!!!!!!!!!!  Wikipedia doesn't need to be edited! 

看到了吗? list 引用的“列表”由 a 提及现在指的是99对象,而不是 1对象,因为它是相同的 list您使用 b[0][0] = 99 访问的.很简单,嗯 ;)

id(a[0]) == id(b[0]) 
#True !!! 

是的,因为虽然我们改变了a[0]的内容引用,我们没有在 a[0] 中更改引用本身和 b[0] - 这更接近维基百科文章在“浅拷贝”部分中描述的内容。