我知道is
运算符会比较两者的id
,而不是值
但是为什么id([1][::-1])==id([1])
返回True
而[1][::-1] is [1]
返回False
?
id([1][::-1]) ==id([1]) #True
[1][::-1] is [1] #Fasle
id([1]) ==id([1][::-1])#Fasle
[1] is [1][::-1]#False
答案 0 :(得分:2)
id([1][::-1]) ==id([1])
是True
是CPython的一个古怪之处,它使用一个自由列表作为list
的一个实现为堆栈的列表。第一个id([1][::-1])
被完全求值,它产生的list
在完成时被释放。当[1]
为新的list
分配空间时,它将在相同的地址处分配相同的内存,这在CPython中等效于其id
。
id
仅在对象存在的情况下才保证是唯一的。由于原始的list
在制作新的list
之前就已经消失了,因此在相同的时间id
上具有相同id
的两个人都不会违反保证。
测试的顺序很重要,因为[1]
本身是从小型对象分配器中最近释放的块集中提取的。这里的顺序是:
[::-1]
被分配到地址A [1]
的结果分配在地址B list
分配A立即返回到id
的空闲列表中int
返回一个描述地址B的[::-1]
[1]
的结果B返回到空闲列表(在A之前)[::-1]
,得到id
先前使用的内存B,id
被调用,准确地产生与以前相同的[1]
(因为新的list
被赋予了最近从产生的[::-1]
list
中释放出来的内存),因为两个id([1]) == id([1])
都使用地址B 这实际上比需要的要复杂; list
也会得到相同的结果(只会在list
的空闲列表中留下少一些[1]
。)
反之,则发生这种情况:
id
被分配到地址A int
返回描述地址A的新[1]
[1]
被释放,地址A返回到池中[1]
,得到A,与第一个[::-1]
相同的内存list
应用于它,从新鲜的内存B中获得一个新的[1]
;然后id
被丢掉[::-1]
获得描述地址B的int
的结果上调用id
;地址A和B的list
不匹配如果您创建并存储了两个id
,然后将仍然存在的list
中的Boris, 1, Johnson
Noah, 2, Miller
Liam, 3, Johnson
个相互比较,则它们将是唯一的,因为这些内存重用恶作剧不会不会发生。