聪明的基于流的python程序不会遇到无限递归

dsp*_*pyz 5 python recursion stream infinite lazy-sequences

我正在玩巧妙的方法为序列A003602创建一个python生成器

这似乎有效,但我无法弄清楚原因.在我看来它应该打无限递归.python是否在某些地方进行了一些我不认识的懒惰评估?

def N():
    i=1
    while True:
        yield i
        i+=1

def interleave(a,b):
    def result():
        x=a()
        y=b()
        while True:
            yield next(x)
            yield next(y)
    return result

def RZ():
    return interleave(N,RZ)()

gen=RZ()
Run Code Online (Sandbox Code Playgroud)

对我来说似乎是因为RZ立即调用interleave返回的方法,而该方法又调用b是RZ(在第一次调用yield之前),这应该是无限递归.但这实际上似乎有效.有谁能解释为什么?

Gar*_*tty 4

生成器(任何带有yield语句的函数)是惰性的。这意味着result()在您请求其中的第一个值之前,它将不会开始处理,而您并没有这样做。

这里的根本原因是你首先要求一个值x。这意味着生成器永远不会询问它的子生成器,直到至少请求第二个值。考虑一个更简单的例子:

def test():
    yield 1
    a = test()
    while True:
        yield next(a)

a = test()
for i in range(10):
    print(next(a))
Run Code Online (Sandbox Code Playgroud)

这有效,就像你的一样。它具有无限递归的潜力,但只有当您要求那么多值时才会达到这种程度。您所要做的就是删除yield 1以获得预期的行为。在你的程序中,只需切换NRZ并询问下一个值 - 你将得到预期的递归。