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,但这从来没有发生过(我没有看到第二次调用print 'extractIngredientInfo' + ingredientLine。有什么具体原因没有发生?

4

3 回答 3

1

我认为这与您实际上并没有递归地使用函数的输出这一事实有关。很难说你想用它做什么,但你可能想用它做点什么。例如:

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

而不仅仅是:

extractIngredientInfo(...,...)
于 2012-08-31T14:27:35.300 回答
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

您必须注意如何在生成器函数中使用递归。你必须小心你的生成器函数产生了什么。

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
于 2012-08-31T14:44:15.000 回答