欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

python尾遞歸函數(shù) python里的遞歸函數(shù)

Python的尾遞歸

原因很多人的都知道,讓我們先回顧一下函數(shù)調(diào)用的大概過程:

堅守“ 做人真誠 · 做事靠譜 · 口碑至上 · 高效敬業(yè) ”的價值觀,專業(yè)網(wǎng)站建設(shè)服務(wù)10余年為成都成都鑿毛機小微創(chuàng)業(yè)公司專業(yè)提供成都企業(yè)網(wǎng)站定制營銷網(wǎng)站建設(shè)商城網(wǎng)站建設(shè)手機網(wǎng)站建設(shè)小程序網(wǎng)站建設(shè)網(wǎng)站改版,從內(nèi)容策劃、視覺設(shè)計、底層架構(gòu)、網(wǎng)頁布局、功能開發(fā)迭代于一體的高端網(wǎng)站建設(shè)服務(wù)。

1)調(diào)用開始前,調(diào)用方(或函數(shù)本身)會往棧上壓相關(guān)的數(shù)據(jù),參數(shù),返回地址,局部變量等。

2)執(zhí)行函數(shù)。

3)清理棧上相關(guān)的數(shù)據(jù),返回。

因此,在函數(shù) A 執(zhí)行的時候,如果在第二步中,它又調(diào)用了另一個函數(shù) B,B 又調(diào)用 C.... 棧就會不斷地增長不斷地裝入數(shù)據(jù),當這個調(diào)用鏈很深的時候,棧很容易就滿 了,這就是一般遞歸函數(shù)所容易面臨的大問題。

而尾遞歸在某些語言的實現(xiàn)上,能避免上述所說的問題,注意是某些語言上,尾遞歸本身并不能消除函數(shù)調(diào)用棧過長的問題,那什么是尾遞歸呢?在上面寫的一般遞歸函數(shù) func() 中,我們可以看到,func(n) 是依賴于 func(n-1) 的,func(n) 只有在得到 func(n-1) 的結(jié)果之后,才能計算它自己的返回值,因此理論上,在 func(n-1) 返回之前,func(n),不能結(jié)束返回。因此func(n)就必須保留它在棧上的數(shù)據(jù),直到func(n-1)先返回,而尾遞歸的實現(xiàn)則可以在編譯器的幫助下,消除這個限制

如何看待以及理解Python的這種尾遞歸優(yōu)化

TCO,tail-call optimization,其實有多種解讀方式。

最常見的解讀方式是:對于尾調(diào)用的函數(shù)調(diào)用,不要浪費棧空間,而要復(fù)用調(diào)用者的棧空間。這樣的結(jié)果就是一長串尾調(diào)用不會爆棧,而沒有TCO的話同樣的調(diào)用就會爆棧。

從這個意義上說,題主貼的那個recipe確實達到了TCO的部分目的:

通過stack introspection查看調(diào)用鏈上的調(diào)用者之中有沒有自己

有的話,通過拋異常來迫使棧回退(stack unwind)到之前的一個自己的frame

在回退到的frame接住異常,拿出后來調(diào)用的參數(shù),用新參數(shù)再次調(diào)用自己

這樣就可以讓尾遞歸不爆棧。但這樣做性能是沒保證的…而且對于完全沒遞歸過的一般尾調(diào)用也不起作用。

一種對TCO的常見誤解是:由編譯器或運行時系統(tǒng)把尾調(diào)用/尾遞歸實現(xiàn)得很快。這不是TCO真正要強調(diào)的事情——不爆棧才是最重要的。也就是說其實重點不在“優(yōu)化”,而在于“尾調(diào)用不爆棧”這個語義保證。

“proper tail-call”的叫法遠比“tail-call optimization”來得合適。

因而像題主說的那種做法,可以算部分TCO,但算不上“性能優(yōu)化”意義上的優(yōu)化。

關(guān)于python遞歸函數(shù)怎樣理解

遞歸的思想主要是能夠重復(fù)某些動作,比如簡單的階乘,次方,回溯中的八皇后,數(shù)獨,還有漢諾塔,分形。

由于堆棧的機制,一般的遞歸可以保留某些變量在歷史狀態(tài)中,比如你提到的return

x

*

power...,

但是某些或許龐大的問題或者是深度過大的問題就需要盡量避免遞歸,因為可能會棧溢出。還有一個問題是~python不支持尾遞歸優(yōu)化!!!!所以~還是盡量避免遞歸的出現(xiàn)。

def

power(x,

n)

if

n

0:

return

1

return

x

*

power(x,

n

-

1)

power(3,

3)

3

*

power(3,

2)

3

*

(3

*

power(3,

1))

3

*

(3

*

(3

*

power(3,

0)))

3

*

(3

*

(3

*

1))

這里n

=

0,

return

1

3

*

(3

*

3)

3

*

9

27

當函數(shù)形參n=0的時候,開始回退~直到第一次調(diào)用power結(jié)束。

如何理解python中的遞歸函數(shù)

遞歸式方法可以被用于解決很多的計算機科學問題,因此它是計算機科學中十分重要的一個概念。

絕大多數(shù)編程語言支持函數(shù)的自調(diào)用,在這些語言中函數(shù)可以通過調(diào)用自身來進行遞歸。計算理論可以證明遞歸的作用可以完全取代循環(huán),因此在很多函數(shù)編程語言(如Scheme)中習慣用遞歸來實現(xiàn)循環(huán)。

計算機科學家尼克勞斯·維爾特如此描述遞歸:

遞歸的強大之處在于它允許用戶用有限的語句描述無限的對象。因此,在計算機科學中,遞歸可以被用來描述無限步的運算,盡管描述運算的程序是有限的。

python 2 遞歸函數(shù)和其它語言,基本沒有差別,只是不支持尾遞歸。無限遞歸最大值為固定的,但可以修改。

作者:黃哥

python為什么不支持尾遞歸

Python本身是不支持尾遞歸的(via),并且對遞歸次數(shù)有限制的,當遞歸次數(shù)超過1000次的時候,就會拋出“RuntimeError: maximum recursion depth exceeded”異常。

Python進階 —— 尾遞歸

下面是筆者的個人理解: 把計算出的值存在函數(shù)內(nèi)部(當然不止尾遞歸)是其計算方法,從而不用在棧中去創(chuàng)建一個新的,這樣就大大節(jié)省了空間。函數(shù)調(diào)用中最后返回的結(jié)果是單純的遞歸函數(shù)調(diào)用(或返回結(jié)果)就是尾遞歸。

實例還是和筆者的上一篇文章相同,建議讀者閱讀 Python —— 遞歸

常規(guī)遞歸階乘:

我們來看一下執(zhí)行過程:

但是如果把上面的函數(shù)寫成如下形式:

我們再看下執(zhí)行過程:

很直觀的就可以看出,這次的 factorial 函數(shù)在遞歸調(diào)用的時候不會產(chǎn)生一系列逐漸增多的中間變量了,而是將狀態(tài)保存在 acc 這個變量中。而這種形式的遞歸,就叫做尾遞歸。

常規(guī)遞斐波那契數(shù)列:

而尾遞歸:

一下子就充滿了逼格,還高效了許多,何樂而不為呢!

當前名稱:python尾遞歸函數(shù) python里的遞歸函數(shù)
瀏覽地址:http://chinadenli.net/article36/hihssg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作品牌網(wǎng)站設(shè)計關(guān)鍵詞優(yōu)化App設(shè)計商城網(wǎng)站自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站