这里有一个尾递归函数

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:在比较中超过了最大递归深度。这只是一个堆栈溢出吗?有办法绕过它吗?


当前回答

正如@alex所建议的,您可以使用生成器函数按顺序而不是递归地完成此操作。

这里是你问题中的等效代码:

def fib(n):
    def fibseq(n):
        """ Iteratively return the first n Fibonacci numbers, starting from 0. """
        a, b = 0, 1
        for _ in xrange(n):
            yield a
            a, b = b, a + b

    return sum(v for v in fibseq(n))

print format(fib(100000), ',d')  # -> no recursion depth error

其他回答

看起来你只需要设置一个更高的递归深度:

import sys
sys.setrecursionlimit(1500)
import sys
sys.setrecursionlimit(1500)

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

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

如果你经常需要改变递归限制(例如在解决编程难题时),你可以定义一个简单的上下文管理器,像这样:

import sys

class recursionlimit:
    def __init__(self, limit):
        self.limit = limit

    def __enter__(self):
        self.old_limit = sys.getrecursionlimit()
        sys.setrecursionlimit(self.limit)

    def __exit__(self, type, value, tb):
        sys.setrecursionlimit(self.old_limit)

然后调用具有自定义限制的函数,您可以这样做:

with recursionlimit(1500):
    print(fib(1000, 0))

从with语句体退出时,递归限制将恢复到默认值。

附注:您可能还想增加Python进程的堆栈大小,以获得较大的递归限制值。例如,这可以通过ulimit shell内置或limits.conf(5)文件来完成。

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

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

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