0

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

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)
4

1 回答 1

5

Generators don't quite work like coroutines. If a generator function recursively calls itself, the recursive call produces another generator object. Control doesn't reenter the generator code like it would in something like Lua, and a yield won't suspend a whole stack of generator calls at once. You have to iterate over the returned generator object and yield its elements:

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

In Python 3.3, the yield from syntax for delegating to a subgenerator was added, so the code would reduce to the following:

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)

This has the advantage of automatically handling send, throw, and a bunch of edge cases that explicitly looping over the subgenerator doesn't deal with.

于 2013-09-12T00:56:32.383 回答