"yield from" 在递归函数中是如何工作的?

How does "yield from" work in recursive functions?

我正在编写一些 python 代码,我需要在递归函数中使用生成器。这是我编写的一些代码来模仿我正在尝试做的事情。这是尝试 1.

def f():
    def f2(i):
        if i > 0:
            yield i
            f2(i - 1)
        
    yield f2(10)

for x in f():
    for y in x:
        print(y)

这只打印 10,使用我在网上找到的 yield from 构造尝试 2。

def f():
    def f2(i):
        if i > 0:
            yield i
            yield from f2(i - 1)
        
    yield from f2(10)


for x in f():
    print(x)

这是我想要的,但我不明白发生了什么,yield from在幕后做了什么,为什么我的第一次尝试不起作用?

您可以将 yield from 视为产生每个项目的 for 循环:

for i in f(10):
    yield i

yield from f(10)相同。换句话说,它 产生 项目 来自 给定的可迭代对象,在这种情况下是另一个生成器。

yield from g() 将在新生成器 g 中递归,从该生成器

的每个 yield 语句中产生

所以

def g1():
    yield from g2()

def g2()
    for i in range(10):
        yield i * 2

你可以认为 g1 中的 yield from 正在其内部展开 g2,扩展成这样的东西

def g1():
    for i in range(10):
        yield i * 2

这不是正在发生的事情,因为你有作用域等,但是在 g1 中执行 yield from g2() 期间,解释器在 g2 中递归产生它产生的每个值,可能递归到另一个生成器。

现在考虑这个生成器

def flatten(maybe_it): 
    try: 
        for i0 in maybe_it: 
            for i1 in flatten(i0): 
                yield i1 
    except TypeError: 
        yield maybe_it 

yield from可以改写为

def flatten(maybe_it): 
    try: 
        for i0 in maybe_it: 
            yield from flatten(i0): 
    except TypeError: 
        yield maybe_it