2011-08-20 12 views
5

ツリー内の各葉からルートまでのすべてのパスを生成したい。私はジェネレータを使って、メモリを節約したい(ツリーは大きくなる可能性があります)ようにしたいと思います。ここに私のコード:Python(yield):ツリー内の葉からルートまでのすべてのパス

def paths(self, acc=[]): 
    if self.is_leaf(): 
     yield [self.node]+acc 

    for child in self.children: 
     child.paths([self.node]+acc) 

しかし、それは動作しません。どうして?ルートで呼び出されると、ツリーは上から下へツリーを横断し、「acc」でノードを収集します。すべてのリーフに "acc"を返します。

is_leaf()はself.childrenが空の場合にtrueです。

答えて

7

:それは代わりに、再帰呼び出しによって生成されたすべての要素を生成する必要があります。他のものは訪問され、上位の関数に渡されますが、上位の関数はそれらを使って何もしません。あなたが必要とするものは、下位の機能から上位の機能にそれらを与えることです:

def paths(self, acc=[]): 
    if self.is_leaf(): 
     yield [self.node]+acc 

    for child in self.children: 
     for leaf_path in child.paths([self.node]+acc): # these two 
      yield leaf_path       # lines do that 

これはトリックを行う必要があります。

+0

私はいつも不思議に思っています - 速い ​​"yield all"コマンドか、あなたが書いた最短のforループですか? – Owen

+0

@Own nopeしかし、これのようにOKですが、それはちょうど2つの単純な行です... –

+5

Python 3.3では、自動的に別のジェネレータからアイテムを生成する 'yield from'ステートメントがあります。その中に 'yield 'をつけて、ジェネレータの式を1行に書くことができます。 – agf

1

現時点では、forループはありませんyield何か。このコードは、rootのみの(直接の)子である葉を生み出す

for child in self.children: 
    for path in child.paths([self.node]+acc): 
     yield path 
関連する問題