【问题标题】:Python generator within a recursive function递归函数中的 Python 生成器
【发布时间】:2013-06-07 04:06:23
【问题描述】:

我正在尝试在递归语句中使用生成器,但没有得到预期的结果。

一点背景知识:我正在使用语法分析树,概念目标是向下递归树,直到我识别出专有名词(由“NNP”标签表示),然后我尝试使用生成器来识别专有名词所在的每个名词短语(由“NP”表示)。

alist = ['ROOT', ['S', ['NP', ['PRP', 'We']], ['VP', ['VBP', 'have'], ['VP', ['VBN', 'received'], ['NP', ['NN', 'information']],
        ['PP', ['IN', 'from'], ['NP', ['NP', ['DT', 'a'], ['NN', 'source']], ['VP', ['VBN', 'entitled'], ['PP', ['TO', 'to'],
        ['NP', ['NN', 'belief']]], [',', ','], ['SBAR', ['IN', 'that'], ['S', ['NP', ['NNP', 'Lincoln']], ['VP', ['VP', ['VBZ', 'has'],
        ['VP', ['VBN', 'paid'], ['NP', ['DT', 'a'], ['JJ', 'hurried'], ['NN', 'visit']], ['PP', ['TO', 'to'],
        ['NP', ['NP', ['DT', 'the'], ['NNP', 'Army']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'Potomac']]]]],
        [',', ','], ['PRN', ['-LRB-', '-LRB-'], ['ADVP', ['RB', 'now']], ['ADJP', ['JJ', 'burrowing'], ['PP', ['IN', 'on'],
        ['NP', ['NP', ['DT', 'the'], ['NN', 'north'], ['NN', 'bank']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'James']]],
        [',', ',']]]], ['-RRB-', '-RRB-']]]], ['CC', 'and'], ['VP', ['VBD', 'satisfied'], ['NP', ['PRP', 'himself']],
        [',', ','], ['PP', ['IN', 'by'], ['NP', ['JJ', 'personal'], ['NN', 'observation']]], [',', ','],
        ['PP', ['IN', 'in'], ['NP', ['NN', 'regard']]], ['PP', ['TO', 'to'], ['NP', ['NP', ['DT', 'the'], ['JJ', 'true'], ['NN', 'situation']],
        ['PP', ['IN', 'of'], ['NP', ['NNS', 'affairs']]]]]]]]]]]]]], ['.', '.']]]

def PullNP(NNP, NPLists):
    if NNP in NPLists:
        print "Pulling relevant NP"
        print NNP
        yield NNP
    for thing in NPLists:
        if NNP in thing:
            PullNP(thing, NPLists)
        else:
            for s in thing:
                if str(type(s)) == "<type 'list'>" and NNP in s: PullNP(s, NPLists)


def RecurseNNP(alist, pastlists=None, count=None):
    if pastlists is None: pastlists = []
    if count is None: count = 0
    if 'NNP' in alist[0]:
        NNPs = PullNP(alist, pastlists)
        print NNPs
        for np in NNPs:
            print np
    else:
        if str(type(alist)) == "<type 'list'>":
            if alist[0] == 'NP':
                pastlists.append(alist)
            for x in alist[1:]:
                RecurseNNP(x, pastlists, count)

RecurseNNP(alist)

如果我运行此代码,我会得到以下输出:

<generator object PullNP at 0x0288B648>
<generator object PullNP at 0x02885558>
<generator object PullNP at 0x02885558>
<generator object PullNP at 0x02885558>

遍历生成器对象不会产生任何输出。但是,如果我删除 yield 语句并仅将 PullNP 作为递归函数运行,我可以确认打印语句包含我希望它们输出的内容。即我希望我的生成器包含这些列表:

Pulling relevant NP
['NP', ['NNP', 'Lincoln']]
Pulling relevant NP
['NP', ['DT', 'the'], ['NNP', 'Army']]
Pulling relevant NP
['NP', ['NP', ['DT', 'the'], ['NNP', 'Army']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'Potomac']]]]
Pulling relevant NP
['NP', ['DT', 'the'], ['NNP', 'Army']]
Pulling relevant NP
['NP', ['NP', ['DT', 'the'], ['NNP', 'Army']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'Potomac']]]]
Pulling relevant NP
['NP', ['DT', 'the'], ['NNP', 'Potomac']]
Pulling relevant NP
['NP', ['NP', ['DT', 'the'], ['NNP', 'Army']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'Potomac']]]]
Pulling relevant NP
['NP', ['DT', 'the'], ['NNP', 'James']]
Pulling relevant NP
['NP', ['NP', ['DT', 'the'], ['NN', 'north'], ['NN', 'bank']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'James']]], [',', ',']]

我已经阅读了解释生成器和产量的主要堆栈溢出帖子,但我仍然不明白为什么我的生成器没有输出任何东西。

【问题讨论】:

    标签: python recursion generator


    【解决方案1】:

    仅仅调用子生成器不会使生成器(迭代器)运行。您需要迭代返回的值(或对其显式调用next)来运行和使用产生的值。

    这是递归函数。因此,将检索到的项目返回给调用者。注意标有# &lt;---的代码部分

    alist = ['ROOT', ['S', ['NP', ['PRP', 'We']], ['VP', ['VBP', 'have'], ['VP', ['VBN', 'received'], ['NP', ['NN', 'information']],
            ['PP', ['IN', 'from'], ['NP', ['NP', ['DT', 'a'], ['NN', 'source']], ['VP', ['VBN', 'entitled'], ['PP', ['TO', 'to'],
            ['NP', ['NN', 'belief']]], [',', ','], ['SBAR', ['IN', 'that'], ['S', ['NP', ['NNP', 'Lincoln']], ['VP', ['VP', ['VBZ', 'has'],
            ['VP', ['VBN', 'paid'], ['NP', ['DT', 'a'], ['JJ', 'hurried'], ['NN', 'visit']], ['PP', ['TO', 'to'],
            ['NP', ['NP', ['DT', 'the'], ['NNP', 'Army']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'Potomac']]]]],
            [',', ','], ['PRN', ['-LRB-', '-LRB-'], ['ADVP', ['RB', 'now']], ['ADJP', ['JJ', 'burrowing'], ['PP', ['IN', 'on'],
            ['NP', ['NP', ['DT', 'the'], ['NN', 'north'], ['NN', 'bank']], ['PP', ['IN', 'of'], ['NP', ['DT', 'the'], ['NNP', 'James']]],
            [',', ',']]]], ['-RRB-', '-RRB-']]]], ['CC', 'and'], ['VP', ['VBD', 'satisfied'], ['NP', ['PRP', 'himself']],
            [',', ','], ['PP', ['IN', 'by'], ['NP', ['JJ', 'personal'], ['NN', 'observation']]], [',', ','],
            ['PP', ['IN', 'in'], ['NP', ['NN', 'regard']]], ['PP', ['TO', 'to'], ['NP', ['NP', ['DT', 'the'], ['JJ', 'true'], ['NN', 'situation']],
            ['PP', ['IN', 'of'], ['NP', ['NNS', 'affairs']]]]]]]]]]]]]], ['.', '.']]]
    
    def PullNP(NNP, NPLists):
        if NNP in NPLists:
            print "Pulling relevant NP"
            print NNP
            yield NNP
        for thing in NPLists:
            if NNP in thing:
                for nnp in PullNP(thing, NPLists):
                    yield nnp
            else:
                for s in thing:
                    if isinstance(s, list) and NNP in s:
                        for nnp in PullNP(s, NPLists):  # <---
                            yield nnp                   # <---
    
    
    def RecurseNNP(alist, pastlists=None, count=None):
        if pastlists is None: pastlists = []
        if count is None: count = 0
        if 'NNP' in alist[0]:
            NNPs = PullNP(alist, pastlists)
            print NNPs
            for np in NNPs:
                print np
        else:
            if str(type(alist)) == "<type 'list'>":
                if alist[0] == 'NP':
                    pastlists.append(alist)
                for x in alist[1:]:
                    RecurseNNP(x, pastlists, count)
    
    RecurseNNP(alist)
    

    【讨论】:

    • 我觉得最好还是试着解释一下答案,这样其他人也可以使用。
    • @user2316602,你是对的。我更新了答案以解释解决方案,并在代码中标记了相关部分。感谢您的反馈。
    猜你喜欢
    • 2016-04-03
    • 2023-03-24
    • 2012-05-03
    • 2012-01-14
    • 2021-05-22
    • 2016-05-03
    • 2017-02-16
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多