1

Python で再帰がどのように機能するかについて、何かが欠けています。文をトークン化するために、次のメソッドを配置しました。

def extractIngredientInfo(ingredientLine, sectionTitle):

    print 'extractIngredientInfo' + ingredientLine

    # set-up some default values for variables that will contains the extracted datas
    usmeas             = 'N.A'
    othermeas          = 'N.A'

    p_ingredientalt     = re.compile('\(or\s(.*?)\)')
    malt = p_ingredientalt.search(ingredientLine)
    if malt:
        ingredientAlt = malt.group(1)
        ingredientLine = ingredientLine.replace(malt.group(0), '').strip()
        print 'NEW LINE TO TREAT(ALT)' + ingredientLine
        extractIngredientInfo(ingredientLine, sectionTitle)
        usmeas,othermeas = extractOneIngredientInfo(ingredientAlt)
        print 'MALT'
        ingredient 
        yield usmeas, othermeas
        #return;

    p_ingredientpurpose = re.compile('\(for\s(.*?)\)') 
    mpurpose = p_ingredientpurpose.search(ingredientLine)
    if mpurpose:
        ingredientPurpose = mpurpose.group(1)
        ingredientLine = ingredientLine.replace(mpurpose.group(0), '').strip()
        print 'NEW LINE TO TREAT(FOR)' + ingredientLine
        extractIngredientInfo(ingredientLine, sectionTitle)
        usmeas,othermeas = extractOneIngredientInfo(ingredientPurpose)
        print 'MPURPOSE'
        yield usmeas,othermeas
        #return;

    usmeas,othermeas = extractOneIngredientInfo(ingredientLine)
    print 'FINAL'
    yield usmeas, othermeas

この関数を呼び出しているときmaltに、再帰関数の即時呼び出しにつながる一致がありますextractIngredientInfoが、これは決して起こりません (への 2 番目の呼び出しは表示されませんprint 'extractIngredientInfo' + ingredientLine。これが発生しない特定の理由はありますか? ?

4

3 に答える 3

1

関数はyieldステートメントを使用するため、ジェネレーターを返します。次の値を要求するまで、ジェネレーターは一時停止されます。

.next()これは、ジェネレーター関数は、呼び出すか、ループ内でイテレーターとして使用するまで何もしないことを意味します。

>>> def foo():
...     print 'Foo called'
...     yield 'bar'
...     print 'Still in foo'
...     yield 'baz'
... 
>>> foogen = foo()
>>> foogen.next()
Foo called
'bar'
>>> foogen.next()
Still in foo
'baz'
>>> for val in foo():
...     pass
... 
Foo called
Still in foo

generatorを呼び出すまでメッセージFoo calledが表示されないことに注意してください。.next()

再帰関数を呼び出すだけですが、それはジェネレーターを返し、それを破棄します。コード自体は保持されているため、実行されることはありません。代わりに結果をループします。

for res in extractIngredientInfo(ingredientLine, sectionTitle):
    yield res

ここで、ネストされたジェネレーター関数の結果を実際に反復処理し、それらを呼び出し元 (外側のネストされたジェネレーター関数のコンシューマー) に渡します。

于 2012-08-31T14:39:58.080 に答える
1

これは、実際には関数の出力を再帰的に使用していないという事実に関係していると思います。これで何をしたいのかを言うのは難しいですが、おそらくそれで何かしたいと思うでしょう。例えば:

 for res in  extractIngredientInfo(...,...):
     yield res

代わりに:

extractIngredientInfo(...,...)
于 2012-08-31T14:27:35.300 に答える
1

ジェネレーター関数で再帰を使用する方法に注意する必要があります。ジェネレーター関数が生成するものに注意する必要があります。

def gen_f(n):
    for i in xrange(n):
        yield "hello"

def recursive_f(n):
    yield "hello"
    if n>0: for line in recursive_f(n-1): yield line
    # the above line is the tricky one, you might be tempted to
    # yield recursive_f(n-1) # but it won't work.

どちらも同等です。呼び出す方法の 1 つは次のとおりです。

for yield_statement in gen_f(10): print yield_statement
于 2012-08-31T14:44:15.000 に答える