zoukankan      html  css  js  c++  java
  • 练习题-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允许的最大递归层数是多少呢?我们实验下:

    复制代码
    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;复杂到人工智能等。
    合理使用递归能让我们的程序具有简洁和强的可读性。

  • 相关阅读:
    周赛F题 POJ 1458(最长公共子序列)
    HDU 4720 Naive and Silly Muggles 2013年四川省赛题
    HDU 4716 A Computer Graphics Problem 2013年四川省赛题
    SCU 4440 Rectangle 2015年四川省赛题
    SCU 4436 Easy Math 2015年四川省赛题
    大数模板——六种实现了加减乘除和求余
    HDU 1002 A + B Problem II
    CodeForces 689C  Mike and Chocolate Thieves
    CodeForces 689A -Mike and Cellphone
    CodeForces 595B
  • 原文地址:https://www.cnblogs.com/shishibuwan/p/12780181.html
Copyright © 2011-2022 走看看