问题在Python中调用递归函数

时间:2012-08-31 14:22:39

标签: python recursion

我遗漏了一些关于递归如何在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。是否有任何具体原因没有发生?

3 个答案:

答案 0 :(得分:1)

我认为这与你实际上没有递归地使用函数输出的事实有关。很难说你想用它做什么,但你可能想用它做某事。 e.g:

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

而不只是:

extractIngredientInfo(...,...)

答案 1 :(得分: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

请注意在我在生成器上调用Foo called之前,消息.next()的打印方式

您只调用递归函数,但会返回一个然后丢弃的生成器。代码本身永远不会执行,因为它保持不变。转而反过来结果:

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

现在你实际迭代嵌套的生成器函数结果,并将它们传递给调用者(外部嵌套生成器函数的使用者)。

答案 2 :(得分:1)

您必须注意如何使用recursion in a generator function。你必须小心发电机功能的产生。

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