具有收益率的递归斐波那契

时间:2018-11-11 14:17:36

标签: python python-3.x recursion fibonacci yield

我正在尝试在此代码中构建具有收益的斐波那契函数,我的 问题是

  

如何在递归和递归调用中使用yield

def fib(x):
  if(x==0 or x==1 ):
   yield  1
  else:
    yield fib(x-1)+fib(x-2)

y=[i for i in fib(10)]
print(y);

我收到此错误


  

“ +不支持的操作数类型:'generator'和'generator'“

我需要知道如何通过递归使用yield而不出现此错误

1 个答案:

答案 0 :(得分:1)

您希望力量将自己击倒在脚上。

好,你去。 在PEP 380

中的python 3.3+中引入“ yield from”

“转发递归收益” (这与您希望生成器的行为类似。)

def fib_infinity(start = 0, acc = 1):
    yield start + acc
    yield from fib_infinity(acc, start + acc)

i = fib_infinity()
next(i) #1
next(i) #2
next(i) #3
next(i) #5
next(i) #8

请注意,一旦达到最大递归深度,这将出错。

但是,这并不能真正满足我们倾向于尝试向下工作的常规递归函数的需求。但是,似乎可以将递归函数简化为尾递归函数,可以引入yield并加以利用。

尝试2: “后向递归收益”

def fib(n, a = 0, b = 1): 
    if n == 0:
        yield a
    if n == 1: 
        yield b
    yield from fib(n - 1, b, a + b)

y = [next(fib(i)) for i in range(10)]
#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

但是请注意,我们在一个“下一个”调用中获得了输出。现在,放开产量会发生什么?

i = fib(8)
next(i) #21
next(i) #21
next(i) #RecursionError: maximum recursion depth exceeded in comparison

对于最终版本,我们可以通过引入return来使该函数更加安全。

尝试3:#safe适用于非基本情况。

def fib(n, a = 0, b = 1): 
    if n == 0:
        yield a
        return 0
    if n == 1: 
        yield b
        return 0
    yield from fib(n - 1, b, a + b)
i = fib(8)
next(i) #21
next(i) #StopIteration

我想不出要创建具有收益率的递归解决方案的单个方案,并且该方案的缺点似乎很大。但是,只是为了好玩而已。这个问题使我很好奇,可以对此进行一些研究。 但是,我建议您切勿实际这样做。