自引用列表

csr*_*ine 2 python

假设您执行以下操作:

a = [1]
a[0] = a
Run Code Online (Sandbox Code Playgroud)

你最终得到的a等于[[...]].这里发生了什么?这隐含地定义了无限链a指向a的最终结果如何[[...]]

Gar*_*ees 6

你什么都没有看到:

>>> a = []
>>> a[:] = [a] * 4
>>> a
[[...], [...], [...], [...]]
Run Code Online (Sandbox Code Playgroud)

如果你有兴趣在如何工作的CPython的,看到list_reprlistobject.c和类似的功能.基本上,任何可能打印自引用对象Py_ReprEnter的函数在打印之前和Py_ReprLeave完成时都会调用该对象.(参见object.c这些函数的定义.)前者检查对象是否在当前正在打印的对象的线程局部堆栈中找到(如果没有,则推送它); 后者从堆栈中弹出对象.因此,如果Python正在打印列表并发现列表在堆栈上,那必须意味着这是一个自引用列表,并且列表应该缩写,以避免无限循环:

 i = Py_ReprEnter((PyObject*)v);
 if (i != 0) {
     return i > 0 ? PyString_FromString("[...]") : NULL;
 }

 // ...

 Py_ReprLeave((PyObject *)v);
 return result;
Run Code Online (Sandbox Code Playgroud)