python递归生成器失败

时间:2013-09-12 00:49:25

标签: python json recursion nested-loops yield

我有嵌套的json对象它包含列表和dicts ..我想在里面搜索所有'foo'键。 我正在尝试做递归生成器,但是在解析dunno的第二次调用时函数失败,为什么,我甚至只看到'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)

1 个答案:

答案 0 :(得分:5)

生成器不像协同程序那样工作。如果生成器函数以递归方式调用自身,则递归调用会生成另一个生成器对象。 Control不会像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)

这样做的好处是可以自动处理sendthrow,以及一些显式循环子生成器的边缘情况不会处理。