如何从嵌套生成器函数中产生结果?

时间:2012-06-25 20:52:27

标签: python function nested generator yield

我有一个功能,可以在下载时产生结果。出于这个问题的目的,让我说我每秒产生一次刺痛,但我想要一个方便的功能来包裹我的发电机:

import time

def GeneratorFunction(max_val):
    for i in range(0,5):
        time.sleep(1)
        yield "String %d"%i

def SmallGenerator():
    yield GeneratorFunction(3)

for s in SmallGenerator():
    print s

...为什么不打印出我期待的5个字符串呢?相反,它似乎返回生成器函数:

<generator object GeneratorFunction at 0x020649B8>

如何将此字符串作为正常的生成器函数来生成字符串?

5 个答案:

答案 0 :(得分:22)

不敢相信我错过了这个;答案是简单地返回生成器函数并应用适当的参数:

import time

def GeneratorFunction(max_val):
    for i in range(0,max_val):
        time.sleep(1)
        yield "String %d"%i

def SmallGenerator():
    return GeneratorFunction(3) # <-- note the use of return instead of yield

for s in SmallGenerator():
    print s

答案 1 :(得分:18)

您可能必须使用自Python 3.3以来可用的new yield from,称为“delegated generator”。

如果我正确理解了这个问题,我就会遇到同样的问题,并在其他地方找到答案。

我想做这样的事情:

def f():

    def g():

        do_something()
        yield x
        …
        yield y

    do_some_other_thing()
    yield a
    …
    g()  # Was not working.
    yield g()  # Was not what was expected neither; yielded None.
    …
    yield b

我现在用它代替:

yield from g()  # Now it works, it yields x and Y.

我从这个页面得到了答案:Python 3: Using "yield from" in Generators - Part 1 (simeonvisser.com)

答案 2 :(得分:1)

来到这里寻找不同形式的“嵌套产量”,终于找到了隐藏的答案。可能不是最好的,但它的工作原理。

我想要通过注册表树来获取,这是解决方案。

        def genKeys(key):
            for value in key.values():
                yield value
            for subkey in key.subkeys():
                print(subkey)
                for x in genKeys(subkey): #this is the trick
                    continue

答案 3 :(得分:0)

这是另一个从1到10生成乘法表的小例子:

class Gen1:

    def __init__(self, gen2):
        self.gen2 = gen2

    def __iter__(self):    
        for a in range(1, 11):    
            for b in self.gen2:
                yield a * b


class Gen2:    

    def __iter__(self):
        for a in range(1, 11):
            yield a


def main():

    gen2 = Gen2()
    gen1 = Gen1(gen2)

    for v in gen1:
        print(v)

if __name__ == '__main__':
    main()

答案 4 :(得分:0)

我来找嵌套收益的另一种用途。

list_of_lists = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

def iter_all(foo):
    yield foo

    if isinstance(foo, list):
        for i in foo:
            for x in iter_all(i):
                yield x


print([i for i in iter_all(list_of_lists)])

输出:

[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [1, 2, 3], 1, 2, 3, [4, 5, 6], 4, 5, 6, [7, 8, 9], 7, 8, 9]