What is the maximum recursion depth in Python, and how to increase it?

前端 未结 17 2877
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-21 04:14

I have this tail recursive function here:

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


        
相关标签:
17条回答
  • 2020-11-21 05:06

    Looks like you just need to set a higher recursion depth:

    import sys
    sys.setrecursionlimit(1500)
    
    0 讨论(0)
  • 2020-11-21 05:07
    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))
    
    0 讨论(0)
  • 2020-11-21 05:07

    We could also use a variation of dynamic programming bottom up approach

    def fib_bottom_up(n):
    
        bottom_up = [None] * (n+1)
        bottom_up[0] = 1
        bottom_up[1] = 1
    
        for i in range(2, n+1):
            bottom_up[i] = bottom_up[i-1] + bottom_up[i-2]
    
        return bottom_up[n]
    
    print(fib_bottom_up(20000))
    
    0 讨论(0)
  • 2020-11-21 05:11

    Use generators?

    def fib():
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a + b
    
    fibs = fib() #seems to be the only way to get the following line to work is to
                 #assign the infinite generator to a variable
    
    f = [fibs.next() for x in xrange(1001)]
    
    for num in f:
            print num
    

    above fib() function adapted from: http://intermediatepythonista.com/python-generators

    0 讨论(0)
  • 2020-11-21 05:15

    resource.setrlimit must also be used to increase the stack size and prevent segfault

    The Linux kernel limits the stack of processes.

    Python stores local variables on the stack of the interpreter, and so recursion takes up stack space of the interpreter.

    If the Python interpreter tries to go over the stack limit, the Linux kernel makes it segmentation fault.

    The stack limit size is controlled with the getrlimit and setrlimit system calls.

    Python offers access to those system calls through the resource module.

    sys.setrecursionlimit mentioned e.g. at https://stackoverflow.com/a/3323013/895245 only increases the limit that the Python interpreter self imposes on its own stack size, but it does not touch the limit imposed by the Linux kernel on the Python process.

    Example program:

    main.py

    import resource
    import sys
    
    print resource.getrlimit(resource.RLIMIT_STACK)
    print sys.getrecursionlimit()
    print
    
    # Will segfault without this line.
    resource.setrlimit(resource.RLIMIT_STACK, [0x10000000, resource.RLIM_INFINITY])
    sys.setrecursionlimit(0x100000)
    
    def f(i):
        print i
        sys.stdout.flush()
        f(i + 1)
    f(0)
    

    Of course, if you keep increasing setrlimit, your RAM will eventually run out, which will either slow your computer to a halt due to swap madness, or kill Python via the OOM Killer.

    From bash, you can see and set the stack limit (in kb) with:

    ulimit -s
    ulimit -s 10000
    

    The default value for me is 8Mb.

    See also:

    • Setting stacksize in a python script
    • What is the hard recursion limit for Linux, Mac and Windows?

    Tested on Ubuntu 16.10, Python 2.7.12.

    0 讨论(0)
提交回复
热议问题