print(id([]) == id([]))
# prints 'True'
print(id(list()) == id(list()))
# prints 'False'
x = []
y = []
print(id(x) == id(y))
# prints 'False'
在上述代码方面,list()
为什么表现与[]
不同?
答案 0 :(得分:5)
在第三次id
比较中,您将比较两个具有重叠生命周期的对象的ID值。根据{{1}}函数的约定,它必须返回False。您将看到与id
相同的行为。
在前两个list()
比较中,所涉及的对象具有不重叠的生存期。具有非重叠生存期的对象的ID值是否恰好相同是实现的详细信息,您不应依赖于它是一种方式。行为如有更改,恕不另行通知。
在当前的CPython中,ID值恰好与id
相同,因为[]
使用BUILD_LIST
操作码,该操作码调用C函数PyList_New
和{{ 1}}使用释放列表列表头结构的免费列表来加快分配速度:
[]
释放列表时,将释放保存元素指针的缓冲区,但(最大释放列表大小)将释放包含有关诸如对象类型,引用计数,容量等信息的标头。goes on the free list:< / p>
PyList_New
由第一个PyObject *
PyList_New(Py_ssize_t size)
{
...
if (numfree) {
numfree--;
op = free_list[numfree];
_Py_NewReference((PyObject *)op);
创建的列表在第二个static void
list_dealloc(PyListObject *op)
{
...
if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
free_list[numfree++] = op;
else
Py_TYPE(op)->tp_free((PyObject *)op);
Py_TRASHCAN_SAFE_END(op)
}
表达式之前死亡,因此其标题进入空闲列表,然后由第二个[]
重用。 []
值基于此标头的地址,因此两个列表具有相同的ID值。
相反,[]
经过id
和list()
,而tp_new
的{{1}}是tp_init
,而不会通过相同的空闲列表。 list
恰好在不同的内存中分配了两个列表,从而产生了不同的ID值。
答案 1 :(得分:4)
id(object)
返回对象的ID。
如果变量所引用的对象相等(具有相同的内容),则==
表达式的结果为True。
因此,当每次创建新对象时使用list()
构造函数时,其ID均不同,因此,即使立即丢弃了新对象,也会将其求值为false,但会首先创建它,因此不同的ID。
相反,[]
是文字的(一种创建对象的更快方法),并且始终具有相同的ID,但是在创建新对象时,新对象也将获得其新ID。
TLDR; []
是文字,因此具有固定的ID,list()
创建一个新对象,x=[]
y=[]
创建一个新对象对象x和y,因此x
和y
的ID不相同,list()
每次都会创建一个新对象,因此每次调用的ID都不相同。
x = []
也会比x = list()
快,但这只是一个注脚,我不知道如何缩小它的大小,只能像注脚一样把它放进去:)>