一、使用遞歸的背景
創(chuàng)新互聯(lián)公司是一家從事企業(yè)網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、行業(yè)門(mén)戶(hù)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)制作的專(zhuān)業(yè)網(wǎng)站建設(shè)公司,擁有經(jīng)驗(yàn)豐富的網(wǎng)站建設(shè)工程師和網(wǎng)頁(yè)設(shè)計(jì)人員,具備各種規(guī)模與類(lèi)型網(wǎng)站建設(shè)的實(shí)力,在網(wǎng)站建設(shè)領(lǐng)域樹(shù)立了自己獨(dú)特的設(shè)計(jì)風(fēng)格。自公司成立以來(lái)曾獨(dú)立設(shè)計(jì)制作的站點(diǎn)近1000家。
先來(lái)看一個(gè)??接口結(jié)構(gòu):
這個(gè)孩子,他是一個(gè)列表,下面有6個(gè)元素
展開(kāi)children下第一個(gè)元素[0]看看:
發(fā)現(xiàn)[0]除了包含一些字段信息,還包含了 children 這個(gè)字段(喜當(dāng)?shù)瑫r(shí)這個(gè)children下包含了2個(gè)元素:
展開(kāi)他的第一個(gè)元素,不出所料,也含有children字段(人均有娃)
可以理解為children是個(gè)對(duì)象,他包含了一些屬性,特別的是其中有一個(gè)屬性與父級(jí)children是一模一樣的,他包含父級(jí)children所有的屬性。
比如每個(gè)children都包含了一個(gè)name字段,我們要拿到所有children里name字段的值,這時(shí)候就要用到遞歸啦~
二、find_children.py
拆分理解:
1.首先import requests庫(kù),用它請(qǐng)求并獲取接口返回的數(shù)據(jù)
2.若children以上還有很多層級(jí),可以縮小數(shù)據(jù)范圍,定位到children的上一層級(jí)
3.來(lái)看看定義的函數(shù)
我們的函數(shù)調(diào)用:find_children(node_f, 'children')
其中,node_f:json字段
??? children:遞歸對(duì)象
?以下這段是實(shí)現(xiàn)遞歸的核心:
?? if items['children']:
?items['children']不為None,表示該元素下的children字段還有子類(lèi)數(shù)據(jù)值,此時(shí)滿(mǎn)足if條件,可理解為 if 1。
?items['children']為None,表示該元素下children值為None,沒(méi)有后續(xù)可遞歸值,此時(shí)不滿(mǎn)足if條件,可理解為 if 0,不會(huì)再執(zhí)行if下的語(yǔ)句(不會(huì)再遞歸)。
至此,每一層級(jí)中children的name以及下一層級(jí)children的name就都取出來(lái)了
希望到這里能幫助大家理解遞歸的思路,以后根據(jù)這個(gè)模板直接套用就行
(晚安啦~)
源碼參考:
函數(shù)的遞歸調(diào)用
遞歸問(wèn)題是一個(gè)說(shuō)簡(jiǎn)單也簡(jiǎn)單,說(shuō)難也有點(diǎn)難理解的問(wèn)題.我想非常有必要對(duì)其做一個(gè)總結(jié).
首先理解一下遞歸的定義,遞歸就是直接或間接的調(diào)用自身.而至于什么時(shí)候要用到遞歸,遞歸和非遞歸又有那些區(qū)別?又是一個(gè)不太容易掌握的問(wèn)題,更難的是對(duì)于遞歸調(diào)用的理解.下面我們就從程序+圖形的角度對(duì)遞歸做一個(gè)全面的闡述.
我們從常見(jiàn)到的遞歸問(wèn)題開(kāi)始:
1 階層函數(shù)
#include iostream
using namespace std;
int factorial(int n)
{
if (n == 0)
{
return 1;
}
else
{
int result = factorial(n-1);
return n * result;
}
}
int main()
{
int x = factorial(3);
cout x endl;
return 0;
}
這是一個(gè)遞歸求階層函數(shù)的實(shí)現(xiàn)。很多朋友只是知道該這么實(shí)現(xiàn)的,也清楚它是通過(guò)不斷的遞歸調(diào)用求出的結(jié)果.但他們有些不清楚中間發(fā)生了些什么.下面我們用圖對(duì)此做一個(gè)清楚的流程:
根據(jù)上面這個(gè)圖,大家可以很清楚的看出來(lái)這個(gè)函數(shù)的執(zhí)行流程。我們的階層函數(shù)factorial被調(diào)用了4次.并且我們可以看出在調(diào)用后面的調(diào)用中,前面的調(diào)用并不退出。他們同時(shí)存在內(nèi)存中??梢?jiàn)這是一件很浪費(fèi)資源的事情。我們?cè)摯蔚膮?shù)是3.如果我們傳遞10000呢。那結(jié)果就可想而知了.肯定是溢出了.就用int型來(lái)接收結(jié)果別說(shuō)10000,100就會(huì)產(chǎn)生溢出.即使不溢出我想那肯定也是見(jiàn)很浪費(fèi)資源的事情.我們可以做一個(gè)粗略的估計(jì):每次函數(shù)調(diào)用就單變量所需的內(nèi)存為:兩個(gè)int型變量.n和result.在32位機(jī)器上占8B.那么10000就需要10001次函數(shù)調(diào)用.共需10001*8/1024 = 78KB.這只是變量所需的內(nèi)存空間.其它的函數(shù)調(diào)用時(shí)函數(shù)入口地址等仍也需要占用內(nèi)存空間??梢?jiàn)遞歸調(diào)用產(chǎn)生了一個(gè)不小的開(kāi)銷(xiāo).
2 斐波那契數(shù)列
int Fib(int n)
{
if (n = 1)
{
return n;
}
else
{
return Fib(n-1) + Fib(n-2);
}
}
這個(gè)函數(shù)遞歸與上面的那個(gè)有些不同.每次調(diào)用函數(shù)都會(huì)引起另外兩次的調(diào)用.最后將結(jié)果逐級(jí)返回.
我們可以看出這個(gè)遞歸函數(shù)同樣在調(diào)用后買(mǎi)的函數(shù)時(shí),前面的不退出而是在等待后面的結(jié)果,最后求出總結(jié)果。這就是遞歸.
3
#include iostream
using namespace std;
void recursiveFunction1(int num)
{
if (num 5)
{
cout num endl;
recursiveFunction1(num+1);
}
}
void recursiveFunction2(int num)
{
if (num 5)
{
recursiveFunction2(num+1);
cout num endl;
}
}
int main()
{
recursiveFunction1(0);
recursiveFunction2(0);
return 0;
}
運(yùn)行結(jié)果:
1
2
3
4
4
3
2
1
該程序中有兩個(gè)遞歸函數(shù)。傳遞同樣的參數(shù),但他們的輸出結(jié)果剛好相反。理解這兩個(gè)函數(shù)的調(diào)用過(guò)程可以很好的幫助我們理解遞歸:
我想能夠把上面三個(gè)函數(shù)的遞歸調(diào)用過(guò)程理解了,你已經(jīng)把遞歸調(diào)用理解的差不多了.并且從上面的遞歸調(diào)用中我們可以總結(jié)出遞歸的一個(gè)規(guī)律:他是逐級(jí)的調(diào)用,而在函數(shù)結(jié)束的時(shí)候是從最后面往前反序的結(jié)束.這種方式是很占用資源,也很費(fèi)時(shí)的。但是有的時(shí)候使用遞歸寫(xiě)出來(lái)的程序很容易理解,很易讀.
為什么使用遞歸:
1 有時(shí)候使用遞歸寫(xiě)出來(lái)的程序很容易理解,很易讀.
2 有些問(wèn)題只有遞歸能夠解決.非遞歸的方法無(wú)法實(shí)現(xiàn).如:漢諾塔.
遞歸的條件:
并不是說(shuō)所有的問(wèn)題都可以使用遞歸解決,他必須的滿(mǎn)足一定的條件。即有一個(gè)出口點(diǎn).也就是說(shuō)當(dāng)滿(mǎn)足一定條件時(shí),程序可以結(jié)束,從而完成遞歸調(diào)用,否則就陷入了無(wú)限的遞歸調(diào)用之中了.并且這個(gè)條件還要是可達(dá)到的.
遞歸有哪些優(yōu)點(diǎn):
易讀,容易理解,代碼一般比較短.
遞歸有哪些缺點(diǎn):
占用內(nèi)存資源多,費(fèi)時(shí),效率低下.
因此在我們寫(xiě)程序的時(shí)候不要輕易的使用遞歸,雖然他有他的優(yōu)點(diǎn),但是我們要在易讀性和空間,效率上多做權(quán)衡.一般情況下我們還是使用非遞歸的方法解決問(wèn)題.若一個(gè)算法非遞歸解法非常難于理解。我們使用遞歸也未嘗不可.如:二叉樹(shù)的遍歷算法.非遞歸的算法很難與理解.而相比遞歸算法就容易理解很多.
對(duì)于遞歸調(diào)用的問(wèn)題,我們?cè)谇耙欢螘r(shí)間寫(xiě)圖形學(xué)程序時(shí),其中有一個(gè)四連同填充算法就是使用遞歸的方法。結(jié)果當(dāng)要填充的圖形稍微大一些時(shí),程序就自動(dòng)關(guān)閉了.這不是一個(gè)人的問(wèn)題,所有人寫(xiě)出來(lái)的都是這個(gè)問(wèn)題.當(dāng)時(shí)我們給與的解釋就是堆棧溢出。就多次遞歸調(diào)用占用太多的內(nèi)存資源致使堆棧溢出,程序沒(méi)有內(nèi)存資源執(zhí)行下去,從而被操作系統(tǒng)強(qiáng)制關(guān)閉了.這是一個(gè)真真切切的例子。所以我們?cè)谑褂眠f歸的時(shí)候需要權(quán)衡再三.
一、函數(shù)的定義
函數(shù)是指將一組語(yǔ)句的集合通過(guò)一個(gè)名字(函數(shù)名)封裝起來(lái),想要執(zhí)行這個(gè)函數(shù),只需要調(diào)用函數(shù)名即可
特性:
減少重復(fù)代碼
使程序變得可擴(kuò)展
使程序變得易維護(hù)
二、函數(shù)的參數(shù)
2.1、形參和實(shí)參數(shù)
形參,調(diào)用時(shí)才會(huì)存在的值
實(shí)慘,實(shí)際存在的值
2.2、默認(rèn)參數(shù)
定義:當(dāng)不輸入?yún)?shù)值會(huì)有一個(gè)默認(rèn)的值,默認(rèn)參數(shù)要放到最后
2.3、 關(guān)鍵參數(shù)
定義: 正常情況下,給函數(shù)傳參數(shù)要安裝順序,不想按順序可以用關(guān)鍵參數(shù),只需要指定參數(shù)名即可,(指定了參數(shù)名的就叫關(guān)鍵參數(shù)),但是要求是關(guān)鍵參數(shù)必須放在位置參數(shù)(以位置順序確定對(duì)應(yīng)的參數(shù))之后
2.4、非固定參數(shù)
定義: 如你的函數(shù)在傳入?yún)?shù)時(shí)不確定需要傳入多少個(gè)參數(shù),就可以使用非固定參數(shù)
# 通過(guò)元組形式傳遞
# 通過(guò)列表形式傳遞
# 字典形式(通過(guò)k,value的方式傳遞)
# 通過(guò)變量的方式傳遞
三、函數(shù)的返回值
作用:
返回函數(shù)執(zhí)行結(jié)果,如果沒(méi)有設(shè)置,默認(rèn)返回None
終止函數(shù)運(yùn)行,函數(shù)遇到return終止函數(shù)
四、變量的作用域
全局變量和局部變量
在函數(shù)中定義的變量叫局部變量,在程序中一開(kāi)始定義的變量叫全局變量
全局變量作用域整個(gè)程序,局部變量作用域是定義該變量的函數(shù)
當(dāng)全局變量與局部變量同名是,在定義局部變量的函數(shù)內(nèi),局部變量起作用,其他地方全局變量起作用
同級(jí)的局部變量不能互相調(diào)用
想要函數(shù)里邊的變量設(shè)置成全局變量,可用global進(jìn)行設(shè)置
五、特殊函數(shù)
5.1、嵌套函數(shù)
定義: 嵌套函數(shù)顧名思義就是在函數(shù)里邊再嵌套一層函數(shù)
提示 在嵌套函數(shù)里邊調(diào)用變量是從里往外依次調(diào)用,意思就是如果需要調(diào)用的變量在當(dāng)前層沒(méi)有就會(huì)去外層去調(diào)用,依次內(nèi)推
匿名函數(shù)
基于Lambda定義的函數(shù)格式為: lambda 參數(shù):函數(shù)體
參數(shù),支持任意參數(shù)。
匿名函數(shù)適用于簡(jiǎn)單的業(yè)務(wù)處理,可以快速并簡(jiǎn)單的創(chuàng)建函數(shù)。
# 與三元運(yùn)算結(jié)合
5.3、高階函數(shù)
定義:變量可以指向函數(shù),函數(shù)的參數(shù)可以接收變量,那么一個(gè)函數(shù)就可以接收另一個(gè)函數(shù)作為參數(shù),這種函數(shù)稱(chēng)之為高階函數(shù) 只需要滿(mǎn)足一下任意一個(gè)條件,即是高階函數(shù)
接收一個(gè)或多個(gè)函數(shù)作為輸入
return返回另一個(gè)函數(shù)
5.4、遞歸函數(shù)
定義:一個(gè)函數(shù)可以調(diào)用其他函數(shù),如果一個(gè)函數(shù)調(diào)用自己本身,這個(gè)函數(shù)就稱(chēng)為遞歸函數(shù)
在默認(rèn)情況下Python最多能遞歸1000次,(這樣設(shè)計(jì)師是為了防止被內(nèi)存被撐死)可以通過(guò)sys.setrecursionlimit(1500)進(jìn)行修改
遞歸實(shí)現(xiàn)過(guò)程是先一層一層的進(jìn),然后在一層一層的出來(lái)
必須有一個(gè)明確的條件結(jié)束,要不然就是一個(gè)死循環(huán)了
每次進(jìn)入更深層次,問(wèn)題規(guī)模都應(yīng)該有所減少
遞歸執(zhí)行效率不高,遞歸層次過(guò)多會(huì)導(dǎo)致站溢出
# 計(jì)算4的階乘 4x3x2x1
# 打印數(shù)字從1-100
5.5、閉包現(xiàn)象
定義:內(nèi)層函數(shù)調(diào)用外層函數(shù)的變量,并且內(nèi)存函數(shù)被返回到外邊去了
閉包的意義:返回的函數(shù)對(duì)象,不僅僅是一個(gè)函數(shù)對(duì)象,在該函數(shù)外還包裹了一層作用域,這使得,該函數(shù)無(wú)論在何處調(diào)用,優(yōu)先使用自己外層包裹的作用域
遞歸式方法可以被用于解決很多的計(jì)算機(jī)科學(xué)問(wèn)題,因此它是計(jì)算機(jī)科學(xué)中十分重要的一個(gè)概念。
絕大多數(shù)編程語(yǔ)言支持函數(shù)的自調(diào)用,在這些語(yǔ)言中函數(shù)可以通過(guò)調(diào)用自身來(lái)進(jìn)行遞歸。計(jì)算理論可以證明遞歸的作用可以完全取代循環(huán),因此在很多函數(shù)編程語(yǔ)言(如Scheme)中習(xí)慣用遞歸來(lái)實(shí)現(xiàn)循環(huán)。
計(jì)算機(jī)科學(xué)家尼克勞斯·維爾特如此描述遞歸:
遞歸的強(qiáng)大之處在于它允許用戶(hù)用有限的語(yǔ)句描述無(wú)限的對(duì)象。因此,在計(jì)算機(jī)科學(xué)中,遞歸可以被用來(lái)描述無(wú)限步的運(yùn)算,盡管描述運(yùn)算的程序是有限的。
python 2 遞歸函數(shù)和其它語(yǔ)言,基本沒(méi)有差別,只是不支持尾遞歸。無(wú)限遞歸最大值為固定的,但可以修改。
作者:黃哥
def Sum(m): #函數(shù)返回兩個(gè)值:遞歸次數(shù),所求的值 if m==1:return 1,m return 1+Sum(m-1)[0],m+Sum(m-1)[1]cishu=Sum(10)[0] print cishu def Sum(m,n=1): ... if m==1:return n,m ... return n,m+Sum(m-1,n+1)[1] print Sum(10)[0] 10 print Sum(5)[0] 5
遞歸的思想主要是能夠重復(fù)某些動(dòng)作,比如簡(jiǎn)單的階乘,次方,回溯中的八皇后,數(shù)獨(dú),還有漢諾塔,分形。
由于堆棧的機(jī)制,一般的遞歸可以保留某些變量在歷史狀態(tài)中,比如你提到的return
x
*
power...,
但是某些或許龐大的問(wèn)題或者是深度過(guò)大的問(wèn)題就需要盡量避免遞歸,因?yàn)榭赡軙?huì)棧溢出。還有一個(gè)問(wèn)題是~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
當(dāng)函數(shù)形參n=0的時(shí)候,開(kāi)始回退~直到第一次調(diào)用power結(jié)束。
本文題目:Python遞歸函數(shù)包含 python定義遞歸函數(shù)
文章分享:http://jinyejixie.com/article12/dodoigc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、服務(wù)器托管、網(wǎng)站制作、虛擬主機(jī)、網(wǎng)站改版、用戶(hù)體驗(yàn)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)