簡體   English   中英

問題在Python中調用遞歸函數

[英]Issue calling a recursive function in Python

我遺漏了一些關於遞歸如何在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但這種情況從未發生過(我沒有看到第二次調用print 'extractIngredientInfo' + ingredientLine 。是有什么特別的原因沒有發生這種情況嗎?

我認為這與你實際上沒有遞歸地使用函數輸出這一事實有關。 很難說你想用它做什么,但你可能想用它做點什么 例如:

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

而不只是:

extractIngredientInfo(...,...)

您的函數返回生成器,因為它使用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

請注意,在我在生成器上調用.next()之前, Foo called的消息是如何打印

您只調用遞歸函數,但返回一個然后丟棄的生成器。 代碼本身永遠不會執行,因為它保持不變。 轉而覆蓋結果:

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

現在,您實際迭代嵌套的生成器函數結果,並將它們傳遞給調用者(外部嵌套生成器函數的使用者)。

您必須注意如何在生成器函數中使用遞歸 你必須要小心你的發電機功能。

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.

兩者都是等價的 ,你可以稱之為:

for yield_statement in gen_f(10): print yield_statement

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM