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

前端 未结 17 2878
佛祖请我去吃肉
佛祖请我去吃肉 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:01

    If you often need to change the recursion limit (e.g. while solving programming puzzles) you can define a simple context manager like this:

    import sys
    
    class recursionlimit:
        def __init__(self, limit):
            self.limit = limit
            self.old_limit = sys.getrecursionlimit()
    
        def __enter__(self):
            sys.setrecursionlimit(self.limit)
    
        def __exit__(self, type, value, tb):
            sys.setrecursionlimit(self.old_limit)
    

    Then to call a function with a custom limit you can do:

    with recursionlimit(1500):
        print(fib(1000, 0))
    

    On exit from the body of the with statement the recursion limit will be restored to the default value.

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

    Many recommend that increasing recursion limit is a good solution however it is not because there will be always limit. Instead use an iterative solution.

    def fib(n):
        a,b = 1,1
        for i in range(n-1):
            a,b = b,a+b
        return a
    print fib(5)
    
    0 讨论(0)
  • 2020-11-21 05:01

    We can do that using @lru_cache decorator and setrecursionlimit() method:

    import sys
    from functools import lru_cache
    
    sys.setrecursionlimit(15000)
    
    
    @lru_cache(128)
    def fib(n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 1
    
        return fib(n - 2) + fib(n - 1)
    
    
    print(fib(14000))
    

    Output

    3002468761178461090995494179715025648692747937490792943468375429502230242942284835863402333575216217865811638730389352239181342307756720414619391217798542575996541081060501905302157019002614964717310808809478675602711440361241500732699145834377856326394037071666274321657305320804055307021019793251762830816701587386994888032362232198219843549865275880699612359275125243457132496772854886508703396643365042454333009802006384286859581649296390803003232654898464561589234445139863242606285711591746222880807391057211912655818499798720987302540712067959840802106849776547522247429904618357394771725653253559346195282601285019169360207355179223814857106405285007997547692546378757062999581657867188420995770650565521377874333085963123444258953052751461206977615079511435862879678439081175536265576977106865074099512897235100538241196445815568291377846656352979228098911566675956525644182645608178603837172227838896725425605719942300037650526231486881066037397866942013838296769284745527778439272995067231492069369130289154753132313883294398593507873555667211005422003204156154859031529462152953119957597195735953686798871131148255050140450845034240095305094449911578598539658855704158240221809528010179414493499583473568873253067921639513996596738275817909624857593693291980841303291145613566466575233283651420134915764961372875933822262953420444548349180436583183291944875599477240814774580187144637965487250578134990402443365677985388481961492444981994523034245619781853365476552719460960795929666883665704293897310201276011658074359194189359660792496027472226428571547971602259808697441435358578480589837766911684200275636889192254762678512597000452676191374475932796663842865744658264924913771676415404179920096074751516422872997665425047457428327276230059296132722787915300105002019006293320082955378715908263653377755031155794063450515731009402407584683132870206376994025920790298591144213659942668622062191441346200098342943955169522532574271644954360217472458521489671859465232568419404182043966092211744372699797375966048010775453444600153524772238401414789562651410289808994960533132759532092895779406940925252906166612153699850759933762897947175972147868784008320247586210378556711332739463277940255289047962323306946068381887446046387745247925675240182981190836264964640612069909458682443392729946084099312047752966806439331403663934969942958022237945205992581178803606156982034385347182766573351768749665172549908638337611953199808161937885366709285043276595726484068138091188914698151703122773726725261370542355162118164302728812259192476428938730724109825922331973256105091200551566581350508061922762910078528219869913214146575557249199263634241165352226570749618907050553115468306669184485910269806225894530809823102279231750061652042560772530576713148647858705369649642907780603247428680176236527220826640665659902650188140474762163503557640566711903907798932853656216227739411210513756695569391593763704981001125
    

    Source

    functools lru_cache

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

    It is a guard against a stack overflow, yes. Python (or rather, the CPython implementation) doesn't optimize tail recursion, and unbridled recursion causes stack overflows. You can check the recursion limit with sys.getrecursionlimit:

    import sys
    print(sys.getrecursionlimit())
    

    and change the recursion limit with sys.setrecursionlimit:

    sys.setrecursionlimit(1500)
    

    but doing so is dangerous -- the standard limit is a little conservative, but Python stackframes can be quite big.

    Python isn't a functional language and tail recursion is not a particularly efficient technique. Rewriting the algorithm iteratively, if possible, is generally a better idea.

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

    Of course Fibonacci numbers can be computed in O(n) by applying the Binet formula:

    from math import floor, sqrt
    
    def fib(n):                                                     
        return int(floor(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))+0.5))
    

    As the commenters note it's not O(1) but O(n) because of 2**n. Also a difference is that you only get one value, while with recursion you get all values of Fibonacci(n) up to that value.

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

    I realize this is an old question but for those reading, I would recommend against using recursion for problems such as this - lists are much faster and avoid recursion entirely. I would implement this as:

    def fibonacci(n):
        f = [0,1,1]
        for i in xrange(3,n):
            f.append(f[i-1] + f[i-2])
        return 'The %.0fth fibonacci number is: %.0f' % (n,f[-1])
    

    (Use n+1 in xrange if you start counting your fibonacci sequence from 0 instead of 1.)

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