>>> 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] - 这更接近维基百科文章在“浅拷贝”部分中描述的内容。
