官术网_书友最值得收藏!

1.2.4 遞歸函數

在函數的內部還可以調用函數,不過一般來說再次調用的函數都是其他函數,如果再次調用的函數是函數本身,那么這個函數就是遞歸函數。一個十分經典的例子就是階乘的計算(為了簡化,未考慮0的階乘)。階乘的概念很簡單:n! = nx(n-1)x(n-2)x...2x1。基于此,可以寫出計算階乘的函數,如下所示。

    def factorial_normal(n):
        result = 1
        for i in range(n):
          result = result * n
          n = n -1
        return result

這是一種解決的方法,邏輯比較簡單,下面來看遞歸的實現方式。根據階乘的概念,可以得到n! =nx(n-1)!。基于此,我們可以寫出如下計算階乘的遞歸函數。

    def factorial_recursion(n):
        if n == 1:
          return 1
        return n * factorial_recursion(n -1)

假設執行factorial_recursion(5),其邏輯如下。

    factorial_recursion(5)
    = 5 * factorial_recursion(4)
    = 5 * 4 * factorial_recursion(3)
    = 5 * 4 * 3 * factorial_recursion(2)
    = 5 * 4 * 3 * 2 * factorial_recursion(1)
    = 5 * 4 * 3 * 2 * 1
    = 120

這兩種方法都是可行的,但是很明顯使用遞歸的方式要更加簡捷一些,而且可以清晰地看出計算的邏輯。在后面爬蟲斷線重連機制的實現上就使用了遞歸函數,它使得爬蟲程序更加穩健。除此之外,遞歸在圖的遍歷、數據結構的構造等方面都有十分廣泛的應用。當然,遞歸也有其缺點,在調用次數過多時會造成棧溢出。例如這里計算factorial_recursion(1000)就會報錯:RecursionError: maximum recursion depth exceeded in comparison

注意:可以將遞歸函數改為尾遞歸的形式解決棧溢出問題,其實就相當于循環。但是Python解釋器沒有對尾遞歸進行優化,所以即使使用尾遞歸也會導致棧溢出。此外,Python默認的遞歸次數大約是1000次(不同的機器可能會不同),當然可以通過sys.setrecursionlimit(n)打破遞歸次數的限制,設置為自定義的n次,不過我們不建議這么做,深層次的遞歸會明顯降低程序運行效率。

主站蜘蛛池模板: 兴山县| 通化县| 石泉县| 临泽县| 茶陵县| 彝良县| 英德市| 吉隆县| 平邑县| 绥阳县| 嘉义市| 嵩明县| 宜州市| 普兰店市| 通城县| 乐安县| 海淀区| 安宁市| 曲阳县| 漯河市| 库车县| 利津县| 星子县| 宜章县| 罗定市| 肥东县| 扶风县| 麻栗坡县| 卓资县| 安龙县| 南华县| 云霄县| 长治县| 高州市| 如皋市| 堆龙德庆县| 天台县| 弋阳县| 邻水| 孟州市| 济阳县|