静かなる名辞

pythonとプログラミングのこと


【python】自分自身を要素に持つlist・循環参照するlistなどを作ってみる

 これまでやったことがなかったので、試してみたというだけです。データ構造によってはこういうのを作りたくなることもあるでしょう。

>>> lst = [0]
>>> lst.append(lst)
>>> lst
[0, [...]]

 なるほど、こういう形で印字されるのか。特に問題はなさそう。

 次に、互いに互いを要素に持つ2つのlist。

>>> lst1 = [0]
>>> lst2 = [1]
>>> lst1.append(lst2)
>>> lst2.append(lst1)
>>> lst1
[0, [1, [...]]]
>>> lst2
[1, [0, [...]]]

 循環構造がある場合、このように表記が省略される。

 辞書の場合。

>>> d = {}
>>> d["key"] = d
>>> d
{'key': {...}}
>>> d1 = {}
>>> d2 = {}
>>> d1["key1"] = d2
>>> d2["key2"] = d1
>>> d1
{'key1': {'key2': {...}}}
>>> d2
{'key2': {'key1': {...}}}

 set……はunhashableなのでなし。また、tupleはimmutableなので、上のようにオブジェクトを生成してから値を挿入することができない。ただし要素にlistを持つことは可能なため、それを利用して循環構造を作り出すことはできる。

>>> tup = ([],)
>>> tup[0].append(tup)
>>> tup
([(...)],)
>>> tup[0]
[([...],)]
>>> tup[0][0]
([(...)],)

 numpyも大丈夫そう。

>>> import numpy as np
>>> a = np.array([1], dtype=object)
>>> a
array([1], dtype=object)
>>> a[0] = a
>>> a
array([array(..., dtype=object)], dtype=object)

 要するに、組み込み型やちゃんとしたライブラリのコレクション型においては、適切に文字列に変換されるので特に心配要りません。ただオリジナルのコレクション型を定義するような場合、__repr__および__str__の実装次第では事故る可能性があるでしょう(ナイーブに子要素に対してstrやreprを呼ぶような実装にすると、無限に再帰し得る)。