>>> 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。
发布于 2013-08-16 03:48:22
b[0] = 99第1部分:为什么调用会导致 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)
#FalseFalse,因为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 DESCRIBINGb仍然引用相同的旧list对象,但是b[0]现在引用99对象。您只需将b引用的b中的一个引用替换为对另一个对象的新引用。您有而不是修改了a指向的任何对象!
id(a[0]) == id(b[0])
#FalseFalse,因为1对象与99对象不是同一个对象。
第2部分:维基百科的文章到底在谈论什么?
下面是一个复制操作的示例,您实际上是在“修改B的一个字段所指向的内存地址”,这样您就可以看到复制对象中的后续更改。
a = [[1],[2],[3]]a是对list对象的引用,但现在list对象包含对list对象的三个引用,每个引用都包含对int对象的引用。
b = a[:]和前面一样,您已经让b引用了一个新的、不同的list对象,它引用了与a中引用的相同的三个list对象。这是证据:
id(a) == id(b)
# FalseFalse,因为与以前一样,a和b是对不同list对象的引用。
id(a[0]) == id(b[0])
#True是的,因为和以前一样,a[0]和b[0]都引用同一个对象。这一次它是一个list对象,它不是不可变的,不像int对象--我们实际上可以更改list对象的内容!的地方是不同的:
b[0][0] = 99 我们做到了-我们更改了由引用的list对象的list内容
a[0][0]
# 99 !!!!!!!!!!!!!! Wikipedia doesn't need to be edited!看见?list引用的'list‘现在引用的是99对象,而不是1对象,因为它与使用b[0][0] = 99访问的list相同。很简单,哈;)
id(a[0]) == id(b[0])
#True !!!没错,因为虽然我们更改了a[0]引用的内容,但并没有在a[0]和b[0]中更改引用本身--这更接近维基百科文章在“浅拷贝”一节中描述的内容。
发布于 2013-08-16 02:48:39
但是为什么写入索引"b“会更改id。
因为它们现在不同了。如果要检查a,a[0]仍然是1而不是99,因为b是一个副本。如果您不想要这种行为,就不会执行以下复制:
>>> a = [1,2,3]
>>> b = a
>>> b[0] = 99
>>> a[0]
99相反,你有这样一个:
>>> a = [1,2,3]
>>> b = a[:]
>>> b[0] = 99
>>> a[0]
1由于您标记了deepcopy.只有当列表本身包含可变参数时,这才是重要的。比如说,你有:
>>> from copy import deepcopy
>>> a = [[1,2],[3,4]]
>>> b = a
>>> c = a[:]
>>> d = deepcopy(a)所以a是b,c是浅拷贝,d是深拷贝。
>>> b[0] = 3
>>> a
[3, [3,4]]
>>> c
[[1,2], [3,4]]
>>> d
[[1,2], [3,4]]b与a相同,但副本没有受到影响。
>>> c[1][1] = 'hi'
>>> a
[3, [3, 'hi']]
>>> c
[[1, 2], [3, 'hi']]如果您替换了c的条目,则a不受影响。但是,如果条目中仍然有原始列表,那么修改其中一个仍然会出现在另一个条目中。嵌套列表仍然相同。
>>> d[1][1] = 10
>>> a
[3, [3, 'hi']]
>>> d
[[1, 2], [3, 10]]因为d是一个深拷贝,它复制了列表以及嵌套的列表,所以我们可以随意修改它和它的元素,而不必担心其他副本的混乱。
发布于 2013-08-16 03:42:22
当您将a的浅拷贝复制到b ( b = a[:] )时,您会复制它。b在特定的时间点变成了a的副本--它是一个“快照”。
当您更新b[0] = 99时,您更新了b -- a的副本。你没有更新a。这就是做一个浅拷贝(或深拷贝)的意义--你想要一个具有相同内容的新变量,这样你就可以在不影响原始副本的情况下对拷贝进行修改。
如果您希望b[0] = 99也影响a,那么您不想“复制”a,您只想用另一个名称引用它。你会用b = a。
https://stackoverflow.com/questions/18264983
复制相似问题