为什么 "yield" 在递归函数中起作用

Why does "yield" work in a recursive function

当我尝试实现一个排列函数时,我从网上得到了这段代码。

def permutations(seq):    
    if len(seq) == 1:
        yield seq
    else:
        for i in range(len(seq)):
            perms = permutations(seq[:i] + seq[i+1:])
            for p in perms:
                yield [seq[i], *p]

我试图理解代码但我失败了,因为我无法理解如何递归地使用 yield。我知道每次执行 next(generator) 时,它 运行 主体中的代码并在 yield 语句处停止。但是如果我只执行 next 一次,它怎么能达到基本条件,因为很明显我必须多次递归才能达到基本条件(len == 1)。 根据我的理解,底线的收益率应该是 return.

这样做的原因如下:在条件的递归分支的循环体中,首先执行:

            perms = permutations(seq[:i] + seq[i+1:])

这会在当前递归步骤中创建一个本地生成器对象。

下两行:

            for p in perms:
                yield [seq[i], *p]

迭代该生成器对象生成的所有值,并根据它们生成排列。

yield 语句不会“穿透”递归,但您的代码会收集递归调用产生的值,然后根据它们产生结果。

实际上这里发生了很多屈服 - 与 seq 长度的阶乘成正比,但根据您的输出大小,这是可以预期的。