1、Python的最大递归层数是可以设置的,默认的在window上的最大递归层数是998

递归是一个很有用的处理方式,简单到遍历文件夹、处理XML;复杂到人工智能等。合理使用递归能让我们的程序具有简洁和强的可读性。

默认recursionlimit是1000,可以设置,但设置后也只能跑到四千多,报MemoryError: stack overflow

import sys
sys.setrecursionlimit(100000) # 可以通过sys.setrecursionlimit()进行设置,但是一般默认不会超过3925-3929这个范围
# a = sys.getrecursionlimit() # 可以通过来进行获取现在设置的值
# print(a)
pass
def recursive(n):
print(n)
n += 1
recursive(n)
if __name__ == '__main__':
recursive(1)

运行结果:

4731
4732
4733
4734
Traceback (most recent call last):
File "E:/D/python/cflcode/testcfl/test_0422_01.py", line 15, in recursive
recursive(n)
File "E:/D/python/cflcode/testcfl/test_0422_01.py", line 15, in recursive
recursive(n)
File "E:/D/python/cflcode/testcfl/test_0422_01.py", line 15, in recursive
recursive(n)
[Previous line repeated 996 more times]
File "E:/D/python/cflcode/testcfl/test_0422_01.py", line 13, in recursive
print(n)
MemoryError: stack overflow
Process finished with exit code 1

解决方法:

def fib(count, cur=0, next_=1):
if count <= 1:
yield cur
else:
# Notice that this is the tail-recursive version
# of fib.
yield fib(count-1, next_, cur + next_)
print fib(996)

这样我们用关键字Yield代替Return把原来的函数变成了生成器。这样如果你只传入参数解释器是不会真正运行的!!!

#执行结果

那我们怎么办呢,这里我们使用的技术称为Trampline,我们用一个方法让它不断执行生成器的next(),达到我们的目的。

import types
def tramp(gen, *args, **kwargs):
g = gen(*args, **kwargs)
while isinstance(g, types.GeneratorType):
g=g.next()
return g
print tramp(fib, 996)

#执行结果

3919377061614427623668052985592742430389065042819420493170692719480242247392252775480208752179017313071371501566248877239254299341332131655760767122899079117071192049598939666199865808814650408864891823186505

首先来看看python默认的最大递归层数:

运行环境:Windows 10,x64python环境:python3.5

def foo(n):
print(n)
n+= 1
foo(n)
if __name__== '__main__':
foo(1)

得到的最大数为998,以后就是报错了:RecursionError: maximum recursion depth exceeded while calling a Python object

那么python允许的最大递归层数是多少呢?我们实验下:

import sys
sys.setrecursionlimit(100000)
def foo(n):
print(n)
n += 1
foo(n)
if __name__ == '__main__':
foo(1)

得到的最大数字在3925-3929之间浮动,这个是和计算机有关系的,不然也不会是一个浮动的数字了(数学逻辑讲求严谨)。

我们已经将数字调到足够大了,已经大于系统堆栈,python已经无法支撑到太大的递归了。

对于没有尾递归的编程语言来说,程序运行起来的时候计算机会给当前进程分配栈,每递归一次,计算机就会给当前程序调度一部分来使用,当使用过多了,那么不好意思,我就这么点了。然后,就没有然后了,崩了。python不是尾递归优化的语言,我们不应该使用递归来替代掉循环,循环存在必然有它巨大的意义。递归用于复杂度为O(log(n))的计算是很有意义的,用于O(n)就不怎么好了。

那么有什么好的解决办法呢?当然是有的,比如python的generator,这个是python的一大神器,请参看:http://www.jianshu.com/p/d36746ad845d

总结:

递归是一个很有用的处理方式,简单到遍历文件夹、处理XML;复杂到人工智能等。合理使用递归能让我们的程序具有简洁和强的可读性。