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?)
它之所以改变是因为您在上一行中更改了它。i[0]是指向10,但您将其改为指向100。因此,i[0]和{}现在不再指向同一个点。在
指针(引用)是单向的。10不知道指向它的是什么。100也没有。它们只是记忆中的位置。因此,如果您更改其中i的第一个元素所指向的位置,k并不关心(因为k和{}是不是相同的引用)。k的第一个元素仍然指向它一直指向的对象。在id(i[:]) == id (k[:]) # True (why is this still true if an element just changed?)
这个比较微妙,但请注意:>>> id([1,2,3,4,5]) == id([1,2,3])
True
鉴于
^{pr2}$
长话短说,当你说id([1,2,3,4,5]) == id([1,2,3]),首先发生的是我们创建{}。然后我们通过调用id获取它在内存中的位置。但是,[1,2,3,4,5]是匿名的,因此垃圾回收器会立即回收它。然后,我们创建另一个匿名对象[1,2,3],CPython碰巧决定它应该放在它刚刚清理过的地方。[1,2,3]也会立即删除和清理。但是,如果存储引用,GC就不能挡道,那么引用就不同了。在
可变表示例
如果重新分配可变对象,也会发生同样的情况。下面是一个例子:>>> import copy
>>> a = [ [1,2,3], [4,5,6], [7,8,9] ]
>>> b = copy.copy(a)
>>> a[0].append(123)
>>> b[0]
[1, 2, 3, 123]
>>> a
[[1, 2, 3, 123], [4, 5, 6], [7, 8, 9]]
>>> b
[[1, 2, 3, 123], [4, 5, 6], [7, 8, 9]]
>>> a[0] = [123]
>>> b[0]
[1, 2, 3, 123]
>>> a
[[123], [4, 5, 6], [7, 8, 9]]
>>> b
[[1, 2, 3, 123], [4, 5, 6], [7, 8, 9]]
不同的是,当你说a[0].append(123)时,我们修改的是{}指向的任何内容。恰好b[0]指向同一个对象(a[0]和{}是对相同对象的引用)。在
但是,如果您将a[0]指向一个新的对象(通过赋值,如a[0] = [123]),那么b[0]和{}不再指向同一个地方。在