3

次のことをするとします。

a = [1]
a[0] = a

最終的にはaas equal to になり[[...]]ます。何が起きてる?aこの暗黙的に定義された の無限チェーンの 参照は、どのようにa終了するの[[...]]でしょうか?

4

3 に答える 3

8

あなたは何も見ていない:

>>> a = []
>>> a[:] = [a] * 4
>>> a
[[...], [...], [...], [...]]

これが CPython でどのように機能するかに興味がある場合は、list_reprinlistobject.cおよび同様の関数を参照してください。基本的に、自己参照オブジェクトを出力する可能性のある関数は、出力Py_ReprEnterPy_ReprLeaveと完了時にオブジェクトを呼び出します。(object.cこれらの関数の定義については、 を参照してください。) 前者は、現在印刷中のオブジェクトのスレッド ローカル スタック内にオブジェクトが見つかるかどうかを確認します (見つからない場合はプッシュします)。後者はオブジェクトをスタックからポップします。したがって、Python がリストを出力していて、そのリストがスタック上にあることを発見した場合、それはこれが自己参照リストであることを意味し、無限ループを避けるためにリストを省略しなければなりません:

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

 // ...

 Py_ReprLeave((PyObject *)v);
 return result;
于 2013-04-06T10:05:50.057 に答える
3

リストには、それ自体への参照が含まれています。これ[[...]]は、リストを印刷するときにレンダリングされる方法です。

実装は、無限再帰にならないように最善を尽くします。として既に印刷されているオブジェクトへの参照をレンダリングすることでこれを行います[...]

これにより、間接的な自己参照でも機能します。

>>> a = []
>>> b = [a]
>>> a.append(b)
>>> a
[[[...]]]
>>> b
[[[...]]]

本当に興味がある場合は、CPython のソース コードを調べることができます。Python 2.7.3 では、関連するコードは にありObjects/listobject.cます。

于 2013-04-06T09:53:37.090 に答える
2

つまり、それ自体が 1 つの要素を含むリストであり、それ自体が 1 つの要素を含むリストであるということですa == [a]。または印刷物: の無限数 の後に無限の が続きます。代わりに得られるのは、Python が役に立ちようとしているだけであり、実際には無限の.aa[][[...]][

于 2013-04-06T09:58:25.430 に答える