这里有一个尾递归函数

def recursive_function(n, sum):
    if n < 1:
        return sum
    else:
        return recursive_function(n-1, sum+n)

c = 998
print(recursive_function(c, 0))

它一直工作到n=997,然后它就中断并抛出一个RecursionError:在比较中超过了最大递归深度。这只是一个堆栈溢出吗?有办法绕过它吗?


当前回答

许多人建议增加递归限制是一个很好的解决方案,但它不是,因为总是会有限制。相反,使用迭代解决方案。

def fib(n):
    a,b = 1,1
    for i in range(n-1):
        a,b = b,a+b
    return a
print fib(5)

其他回答

使用一种保证尾部调用优化的语言。或者使用迭代。或者,和装饰师一起玩。

如果你只想得到很少的斐波那契数,你可以使用矩阵法。

from numpy import matrix

def fib(n):
    return (matrix('0 1; 1 1', dtype='object') ** n).item(1)

它的速度很快,因为numpy使用了快速求幂算法。结果是O(log n)比比奈公式好因为它只使用整数。但如果你想让所有的斐波那契数都不超过n,最好是死记硬背。

是的,它是防止堆栈溢出的一种方法。Python(或者更确切地说,CPython实现)没有优化尾部递归,并且无限制的递归会导致堆栈溢出。你可以用sys.getrecursionlimit检查递归限制:

import sys
print(sys.getrecursionlimit())

并使用sys.setrecursionlimit更改递归限制:

sys.setrecursionlimit(1500)

但这样做是危险的——标准限制有点保守,但Python的堆栈框架可能相当大。

Python不是函数式语言,尾递归也不是一种特别有效的技术。如果可能的话,迭代地重写算法通常是一个更好的主意。

这是为了避免堆栈溢出。Python解释器限制了递归的深度,以帮助您避免无限递归,从而导致堆栈溢出。 尝试增加递归限制(sys.setrecursionlimit)或重写不使用递归的代码。

来自Python文档:

sys.getrecursionlimit () 返回递归限制的当前值,即Python解释器堆栈的最大深度。这个限制可以防止无限递归导致C堆栈溢出和Python崩溃。可以通过setrecursionlimit()来设置。

我知道这是一个老问题,但对于那些阅读的人来说,我建议不要使用递归来解决这样的问题——列表要快得多,并且完全避免递归。我将这样实现:

def fibonacci(n):
    f = [0,1,1]
    for i in xrange(3,n):
        f.append(f[i-1] + f[i-2])
    return 'The %.0fth fibonacci number is: %.0f' % (n,f[-1])

(在xrange中使用n+1,如果你从0开始计数你的斐波那契数列,而不是从1开始。)