⬜
自分自身を参照するNodeのlistでの実装(Python)
こんにちは、沙代です。
PythonでNodeをlistで実装するときに、自分自身を参照させたい時ってありますよね。
ちょっと試してみたので、まとめてみました。
環境
MacOS: macOS Montery 12.6.2 (Apple M1 Pro)
iTerm2: 3.5.4
Python: 3.7.0
TL;DR
>>> a = [None, 'generation0'] # 単にa = [] でも可
>>> a[:] = [a, 'generation0'] # 単にa[0] = a でも可
>>> a
[[...], 'generation0']
>>> a[0]
[[...], 'generation0']
>>> a is a[0]
True
詳しく
Nodeを準備します
[親Node, 世代名]
でNodeをlist
で表現したい。
第0世代の親は自分自身としたい。
>>> a = [None, 'generation0']
>>> b = [a, 'generation1']
問題点
>>> a = [a, 'generation0']
>>> a
[[None, 'generation0'], 'generation0']
>>> a[0]
[None, 'generation0']
a
とa[0]
は別物になっています。
解決策
>>> a[:] = [a, 'generation0']
>>> a
[[...], 'generation0']
>>> a[0]
[[...], 'generation0']
>>> a is a[0]
True
a[:]
を使うことで、自分自身に参照させることができました!
(a[0] = a
でも大丈夫です!)
その他
他の例として、functools.lru_cache
の実装では、
Lib/functools.py
root = [] # root of the circular doubly linked list
root[:] = [root, root, None, None] # initialize by pointing to self
として書かれており、この場合は[:]
スライス代入の方が見やすいかもしれません。
最後に
ちょっとサッと実装したいときに便利ですね。コードを共有するとびっくりされてしまうかもしれませんが。汗
Discussion