如何解决python中递归层数过多的异常?

Python中递归函数的调用层数过深,引发异常,报错信息如下所示:

RuntimeError: maximum recursion depth exceeded

如何解决这个问题呢?

喜欢这个问题 | 分享 | 新建回答

回答

东方不败

Mar 1, 2019
2 赞

Python中递归函数的层数是有限的;这算是对系统资源的一种保护机制。

若超出了限制,即函数堆栈溢出,python则会抛出异常信息"RuntimeError: maximum recursion depth exceeded";解决这类异常可以在python程序中手动提高系统对python递归函数层数的上限。

在python程序的一开始处,插入如下代码即可。

import sys
sys.setrecursionlimit(10000) # 10000 is just an example

上述代码中手动设置上限为10000,这个10000只是一个例子,可以根据自己需求去逐步试着提高上限;但这个上限总有极限的。(个人最推荐这种方式,方便简单快捷)



还有一种方式就对递归函数进行优化,把线性递归函数改成尾递归函数。尾递归可以极大地减少函数的堆栈耗用,从而提高递归函数的层数限制。(不过后面会说到个人为啥并不推荐使用尾递归)

所谓的尾递归,就是函数中所有递归形式的调用都出现在函数的最末尾,而且递归调用的函数体的返回值不属于某个表达式的一部分。简而言之,就是在最后的地方return一个函数。这样就可以大大减少函数堆栈耗用,提高运行效率,增加递归的层数限制。

举一个例子,若用普通的线性递归来求正整数n的阶乘,如下:

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n-1)

若改成尾递归,则如下所示:

def factorial(n):
    return factorial_iteration(n, 1)

def factorial_iteration(n, r):
    if n == 1:
        return r
    return factorial_iteration(n - 1, n * r)



法无常法,水无常形。很多地方都推崇的尾递归优化,个人极其不推荐这种优化方式。原因是综合的,首先尾递归优化,并不符合python语言的设计初衷,python语言的设计初衷与ruby语言类似,ruby语言之父松本行弘就提到过这类语言是从人的角度来设计的,而不是站在机器的角度。

从人的角度是为了提高开发的效率,让人们更舒服地更轻松地来通过编程而实现功能;同样求一个阶乘,0.001s和0.01s在大多数的场景中对人来说都是无关痛痒的。分清瓶颈问题很重要,当运行效率不是瓶颈问题时,何必花力气去写如何让机器更舒服的代码呢?反而应该考虑开发者是否舒服。

递归函数本身就是在解决相对复杂的问题;为了把复杂的问题简单化;这时更应该力求的是代码逻辑的清晰简洁。显而易见,尾递归优化的方式让代码逻辑更加复杂了,明显不如未优化前的代码清晰简洁。

再者,python中提供了手动提高上限的方式。按照最初的方法来弄,鱼和熊掌已能兼得,又何必去尾递归优化呢?另外,经过尾递归优化的程序也是存在上限的,经测试并不见得能提高多少上限。

综上所述,个人极其不推荐尾递归优化,这是一种玷污。(这些都属于个人观点,仅供参考)



如果真是要处理一个计算量很大的问题,且到达了“不得不”的境地。可考虑反其道而行的代码优化方式:放弃递归,用for循环加函数的方式来处理吧...