python递归生成器失败

python递归生成器失败,python,json,recursion,nested-loops,yield,Python,Json,Recursion,Nested Loops,Yield,我有一个嵌套的json对象,它包含列表和dict。。我想在里面搜索所有的“foo”键。 我试图做递归生成器,但函数在第二次调用parse时失败了。不知道为什么,我甚至只看到一次“in”输出。看起来解释器不会再次进入解析等。。帮我理解我错在哪里 def parse(d,key): print('in') if type(d)==type({}): if key in d: yield d[key] for k in d:

我有一个嵌套的json对象,它包含列表和dict。。我想在里面搜索所有的“foo”键。 我试图做递归生成器,但函数在第二次调用parse时失败了。不知道为什么,我甚至只看到一次“in”输出。看起来解释器不会再次进入解析等。。帮我理解我错在哪里

def parse(d,key):
    print('in')
    if type(d)==type({}):
        if key in d:
            yield d[key]
        for k in d:
            parse(d[k],key)
    if type(d)==type([]):
        for i in d:
            parse(i,key)

发电机不像协同程序那样工作。如果生成器函数递归调用自身,则递归调用将生成另一个生成器对象。控件不会像在Lua中那样重新输入生成器代码,并且
yield
不会一次挂起整个生成器调用堆栈。您必须迭代返回的生成器对象并生成其元素:

def parse(d,key):
    print('in')
    if type(d)==type({}):
        if key in d:
            yield d[key]
        for k in d:
            for item in parse(d[k],key):
                yield item
    if type(d)==type([]):
        for i in d:
            for item in parse(i,key):
                yield item
在Python 3.3中,添加了用于委托给子生成器的
yield from
语法,因此代码将简化为以下内容:

def parse(d,key):
    print('in')
    if type(d)==type({}):
        if key in d:
            yield d[key]
        for k in d:
            yield from parse(d[k],key)
    if type(d)==type([]):
        for i in d:
            yield from parse(i,key)

这具有自动处理
发送
抛出
,以及显式循环子生成器无法处理的大量边缘情况的优点。

生成器的工作方式与协同例程不同。如果生成器函数递归调用自身,则递归调用将生成另一个生成器对象。控件不会像在Lua中那样重新输入生成器代码,并且
yield
不会一次挂起整个生成器调用堆栈。您必须迭代返回的生成器对象并生成其元素:

def parse(d,key):
    print('in')
    if type(d)==type({}):
        if key in d:
            yield d[key]
        for k in d:
            for item in parse(d[k],key):
                yield item
    if type(d)==type([]):
        for i in d:
            for item in parse(i,key):
                yield item
在Python 3.3中,添加了用于委托给子生成器的
yield from
语法,因此代码将简化为以下内容:

def parse(d,key):
    print('in')
    if type(d)==type({}):
        if key in d:
            yield d[key]
        for k in d:
            yield from parse(d[k],key)
    if type(d)==type([]):
        for i in d:
            yield from parse(i,key)
这具有自动处理
发送
抛出
,以及显式循环子生成器无法处理的一系列边缘情况的优点