python不能無限的遞歸調(diào)用下去原杂。并且當(dāng)輸入的值太大,遞歸次數(shù)太多時您机,python 都會報錯
RecursionError: maximum recursion depth exceeded in comparison
首先說結(jié)論穿肄,python解釋器這么會限制遞歸次數(shù),這么做為了避免"無限"調(diào)用導(dǎo)致的堆棧溢出际看。
tail recursion
tail recursion 就是指在程序最后一步執(zhí)行遞歸咸产。這種函數(shù)稱為 tail recursion function。舉個例子:
def fact(n):
if n == 0:
return 1
return n * fact(n-1)
這個函數(shù)就是普通的遞歸函數(shù)仿村,它在遞歸之后又進行了 乘 的操作锐朴。 這種普通遞歸,每一次遞歸調(diào)用都會重新推入一個調(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 的好處是每一次都計算完,將結(jié)果傳遞給下一次調(diào)用衣迷,然后本次調(diào)用任務(wù)就結(jié)束了畏鼓,不會參與到下一次的遞歸調(diào)用。這種情況下壶谒,只重復(fù)用到了一個堆棧云矫。因此可以優(yōu)化結(jié)構(gòu)。就算是多次循環(huán)汗菜,也不會出現(xiàn)棧溢出的情況让禀。這就是 tail recursion optimization 挑社。
c和c++都有這種優(yōu)化, python沒有巡揍,所以限制了調(diào)用次數(shù)痛阻,就是為了防止無限遞歸造成的棧溢出。
如果遞歸次數(shù)過多腮敌,導(dǎo)致了開頭的報錯阱当,可以使用 sys
包手動設(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時,正常輸出結(jié)果.
# 當(dāng)你輸入1000時糜工。python 會報錯: maximum recursion depth exceeded in comparison
手動放大 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))
# 此時輸入1000弊添, 有正常計算結(jié)果返回