在閱讀http://www.cnblogs.com/skabyy/p/3451780.html這篇文章的時候,實驗yield的流式迭代素數的時候發現有個問題,故詳細記錄下來。
首先來看看python默認的最大遞歸層數:
運行環境:Windows 10,x64
python環境:python3.5
def foo(n):
print(n)
n += 1
foo(n)
if __name__ == '__main__':
foo(1)
得到的最大數為998,以后就是報錯了:RecursionError: maximum recursion depth exceeded while calling a Python object
那么python允許的最大遞歸層數是多少呢?我們實驗下:
import sys sys.setrecursionlimit(100000) def foo(n): print(n) n += 1 foo(n) if __name__ == '__main__': foo(1)
得到的最大數字在3925-3929之間浮動,這個是和計算機有關系的,不然也不會是一個浮動的數字了(數學邏輯講求嚴謹)。
我們已經將數字調到足夠大了,已經大於系統堆棧,python已經無法支撐到太大的遞歸了。
對於沒有尾遞歸的編程語言來說,程序運行起來的時候計算機會給當前進程分配棧,每遞歸一次,計算機就會給當前程序調度一部分來使用,當使用過多了,那么不好意思,我就這么點了。然后,就沒有然后了,崩了。python不是尾遞歸優化的語言,我們不應該使用遞歸來替代掉循環,循環存在必然有它巨大的意義。遞歸用於復雜度為O(log(n))的計算是很有意義的,用於O(n)就不怎么好了。
那么有什么好的解決辦法呢?當然是有的,比如python的generator,這個是python的一大神器,請參看:http://www.jianshu.com/p/d36746ad845d
總結:
遞歸是一個很有用的處理方式,簡單到遍歷文件夾、處理XML;復雜到人工智能等。
合理使用遞歸能讓我們的程序具有簡潔和強的可讀性。
