练习题-Python的最大递归层数

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

解决方法:

python的generator,这个是python的一大神器,请参看:http://www.jianshu.com/p/d36746ad845d

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把原来的函数变成了生成器。这样如果你只传入参数解释器是不会真正运行的!!!
#执行结果
<generator object fib at 0x02B00D00>
那我们怎么办呢,这里我们使用的技术称为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的最大递归层数详解

 

在阅读http://www.cnblogs.com/skabyy/p/3451780.html这篇文章的时候,实验yield的流式迭代素数的时候发现有个问题,故详细记录下来。

 

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

运行环境:Windows 10,x64
python环境:python3.5

1 2 3 4 5 6 7 def foo(n):     print(n)     += 1     foo(n)   if __name__ == '__main__':     foo(1)

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

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

练习题-Python的最大递归层数
import sys
sys.setrecursionlimit(100000)

def foo(n):
    print(n)
    n += 1
    foo(n)
        
if __name__ == '__main__':
    foo(1)
练习题-Python的最大递归层数

 

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

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

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

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

 

总结:

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

上一篇:linux – FFmpeg无法识别预设,即使它确实存在Ubuntu 12.04


下一篇:Greenplum(PostgreSql)使用 with recursive 实现树形结构递归查询并插入新表