python 遞歸限制

python不能無限的遞歸調(diào)用下去。并且當(dāng)輸入的值太大,遞歸次數(shù)太多時(shí),python 都會(huì)報(bào)錯(cuò)

RecursionError: maximum recursion depth exceeded in comparison

首先說結(jié)論,python解釋器這么會(huì)限制遞歸次數(shù),這么做為了避免"無限"調(diào)用導(dǎo)致的堆棧溢出。

tail recursion

tail recursion 就是指在程序最后一步執(zhí)行遞歸。這種函數(shù)稱為 tail recursion function。舉個(gè)例子:

def fact(n):
    if n == 0:
        return 1

    return n * fact(n-1)

這個(gè)函數(shù)就是普通的遞歸函數(shù),它在遞歸之后又進(jìn)行了 的操作。 這種普通遞歸,每一次遞歸調(diào)用都會(huì)重新推入一個(gè)調(diào)用堆棧。
把上述調(diào)用改成 tail recursion function

def fact(n, a=1):
    if n == 0:
        return a

    return fact(n - 1, n * a)

tail recursion 的好處是每一次都計(jì)算完,將結(jié)果傳遞給下一次調(diào)用,然后本次調(diào)用任務(wù)就結(jié)束了,不會(huì)參與到下一次的遞歸調(diào)用。這種情況下,只重復(fù)用到了一個(gè)堆棧。因此可以優(yōu)化結(jié)構(gòu)。就算是多次循環(huán),也不會(huì)出現(xiàn)棧溢出的情況。這就是 tail recursion optimization 。

c和c++都有這種優(yōu)化, python沒有,所以限制了調(diào)用次數(shù),就是為了防止無限遞歸造成的棧溢出。

如果遞歸次數(shù)過多,導(dǎo)致了開頭的報(bào)錯(cuò),可以使用 sys 包手動(dòng)設(shè)置recursion的limit

def fact(n):
    if n == 0:
        return 1

    return n * fact(n-1)

if __name__ == '__main__':
    f = int(input('input number: \n'))
    print(fact(f))

# 當(dāng)你輸入100時(shí),正常輸出結(jié)果. 
# 當(dāng)你輸入1000時(shí)。python 會(huì)報(bào)錯(cuò): maximum recursion depth exceeded in comparison

手動(dòng)放大 recursionlimit 限制:

import sys

sys.setrecursionlimit(10**6)

def fact(n):
    if n == 0:
        return 1

    return n * fact(n-1)

if __name__ == '__main__':
    f = int(input('input number: \n'))
    print(fact(f))

# 此時(shí)輸入1000, 有正常計(jì)算結(jié)果返回
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容