Pythonでの再帰的yieldの書き方

再帰構造の走査でgeneratorを使うと、generatorメソッドの再帰呼び出しになるだろう。この場合、generatorは実際にイテレートして、その値ごとにyieldしなおす必要が出てくる。

for v in self.child.iter():
  yield v
# yield self.child.iter() ジェネレータオブジェクト自体をyieldしてしまうので、間違い

Python 2.5ではyield式ができたので、list comprehensionを無理やり使えば式にはできる

[(yield v) for v in self.child.iter()]
# 式としてみなされるには、この()は必須っぽい

1行にするだけなら for文を1行で書けばいい。あと値を受ける変数も_を使えばなんとなく気にならなくなるかもw

for _ in self.child.iter(): yield _

字数的には多いし、きれいじゃない。yield for self.child.iter()とか使えればいいのに。

class Nil:
    def __iter__(self):
        raise StopIteration()
        yield
        pass
    pass
nil = Nil()

class Node:
    def __init__(self, value, child=nil, brother=nil):
        self.value = value
        self.child = child
        self.brother = brother
        pass

    def __iter__(self):
        yield self.value
        #[(yield _) for _ in self.child]
        for _ in self.child: yield _
        for _ in self.brother: yield _
        pass
    pass


tree = Node(1, Node(2, Node(3)), Node(4))

for v in tree:
    print v
    pass