解決遞歸調用棧溢出的方法是經過尾遞歸優化,事實上尾遞歸和循環的效果是同樣的,因此,把循環當作是一種特殊的尾遞歸函數也是能夠的。函數
尾遞歸是指,在函數返回的時候,調用自身自己,而且,return語句不能包含表達式。這樣,編譯器或者解釋器就能夠把尾遞歸作優化,使遞歸自己不管調用多少次,都只佔用一個棧幀,不會出現棧溢出的狀況。優化
上面的fact(n)
函數因爲return n * fact(n - 1)
引入了乘法表達式,因此就不是尾遞歸了。要改爲尾遞歸方式,須要多一點代碼,主要是要把每一步的乘積傳入到遞歸函數中:code
def fact(n): return fact_iter(n, 1) def fact_iter(num, product): if num == 1: return product return fact_iter(num - 1, num * product)
能夠看到,return fact_iter(num - 1, num * product)
僅返回遞歸函數自己,num - 1
和num * product
在函數調用前就會被計算,不影響函數調用。遞歸
fact(5)
對應的fact_iter(5, 1)
的調用以下:編譯器