最新 次の日記(2013年09月16日)» 編集

ema log


2013年09月14日 [長年日記]

_ [Programming] Python のジェネレータによる外部イテレータ

ツリーをトラバースする必要があったんだけど、visitor が無く while 文で順番にたぐるコードを書いた

node = GetRoot()
while node:
    # ガード節
    if condition_is_not_valid:
        # スキップ
        node = GetNextNode(node)
        continue

    # 処理
    proc
    # 次へ
    node = GetNextNode(node)

ただ、これだとガード節を書きたいときに、continue の前に次を取得するコードをコピペしないと駄目で、かといってネストを深くしたくないし、goto 文も無いのでどうしようかなぁと思ったけど、よくよく考えれば外部イテレータに思いあたり。

class ObjectIterator:
    def __iter__(self):
        node = GetRoot()
        while node:
            yield node
            node = GetNextNode(node)

こんな感じのイテレータを用意して、for 文で回せば良かった。すっきり。

for obj in ObjectIterator():
    # ガード節
    if condition_is_not_valid: continue
    # 処理
    proc

なるほど。Ruby だと Enumerable なモンキーパッチで内部イテレータにしたくなるけど、Python だと外部イテレータを書けば良いということか。