遞歸函數(shù)不是帝龜?。?/strong>:一個(gè)函數(shù)調(diào)用了它自己本身就叫做遞歸
定義一個(gè)比較糟糕的函數(shù)調(diào)用自身:
你會(huì)發(fā)現(xiàn)它調(diào)用test()的時(shí)候,它唯一的函數(shù)內(nèi)容是打印myoffer然后returntest(),再回到定義函數(shù),打印myoffer,然后return test()一直循環(huán)往復(fù);
這就有疑問了
是不是會(huì)一直執(zhí)行下去呢,理論上它會(huì)一直執(zhí)行下去直到消耗掉所有內(nèi)存,其實(shí)Python3設(shè)置了遞歸默認(rèn)深度是100層,到達(dá)之后就會(huì)報(bào)錯(cuò)。不過在寫爬蟲工具的時(shí)候就可能不止100層了,所以我們就要自力更生了。
這樣深層次的調(diào)用就會(huì)導(dǎo)致“棧溢出”就好比一個(gè)杯子它有自己的最大容量,超過了這個(gè)容量就會(huì)溢出。
來(lái)個(gè)人道點(diǎn)的例子解釋帝龜和棧溢出:求1-100的階乘。
先分析:
想要得到的結(jié)果1×2×3×…×100
可以拆分成100×函數(shù)(99)【函數(shù)(99)可以完成1×2×3×…×99 】
可以拆分成 99×函數(shù)(98)【函數(shù)(99)可以完成1×2×3×…×98】
……
……
…….
可以拆分成2×函數(shù)(1)【函數(shù)(1)可以完成1×2】正確的解法如下
現(xiàn)在來(lái)了解一下這只龜,先拿一個(gè)print(test(3))來(lái)剖析
第一次程序執(zhí)行時(shí)會(huì)先傳入3,替換所有numbers,當(dāng)執(zhí)行到test(3-1)又要調(diào)用test()然后就會(huì)傳入2,變?yōu)閠est(numbers=2)下面的程序。
同理執(zhí)行到test(2-1)又要再次調(diào)用test(),變?yōu)閠est(numbers=1)下面的程序
直接執(zhí)行else后的程序返回1
注意:一個(gè)函數(shù)調(diào)用return有兩種含義:返回一個(gè)值或結(jié)束當(dāng)前函數(shù);
所以說當(dāng)return 1時(shí)第二個(gè)程序中的test(2-1)就會(huì)替換為return 2×1
接著就會(huì)執(zhí)行這個(gè)return 2×1時(shí),第一個(gè)程序中的test(3-1)就會(huì)替換為return 3×2×1
當(dāng)執(zhí)行這個(gè)return 3×2×1時(shí),程序就會(huì)執(zhí)行結(jié)果print(test(3)),同理要執(zhí)行print(test(100))也是一樣的原理,這就是帝龜。
好啦現(xiàn)在理解了帝龜就可以更透徹明白棧溢出了
第一步當(dāng)程序執(zhí)行print(test(3))這玩意的時(shí)候,就要調(diào)用函數(shù)test(number=3),然后執(zhí)行下面這個(gè)函數(shù)
執(zhí)行好后呢,先把這個(gè)3放到杯子底下,然后執(zhí)行numbers=2,就把2再放到杯子里,一層層上疊(就是在內(nèi)存中存儲(chǔ)好,為了當(dāng)返回執(zhí)行return2×1時(shí),能夠識(shí)別3×test(3-1)并替換為return 3×2×1,其它的類似,當(dāng)返回執(zhí)行return1時(shí),能夠識(shí)別2×test(2-1)并替換為return 2×1)
所以說每次調(diào)用自己函數(shù)的時(shí)候呢就要在杯子中裝點(diǎn)東西,當(dāng)你調(diào)用循環(huán)的次數(shù)是1000000或者更大,杯子總有滿的時(shí)候,等到裝不下的時(shí)候就叫做“棧溢出”了。
至于為甚么叫“棧(stack)溢出”怎么上檔次的名字呢
上面說了存東西的時(shí)候都是從杯底往上一層層的疊加(調(diào)用一次函數(shù),棧就會(huì)加一層棧幀),到你要取的時(shí)候只能先從上面拿了(函數(shù)返回棧就會(huì)減一層棧幀),杯子是有最大容量的(棧的大小不是無(wú)限的,遞歸調(diào)用過多就會(huì)棧溢出)總結(jié):這種存儲(chǔ)特性“先進(jìn)后出”
注意:為什么上面的例子numbers=1要多帶帶處理呢,因?yàn)楫?dāng)numbers傳入1時(shí),就會(huì)變成test(1-1),沒有到0的階乘,這樣結(jié)果就會(huì)變成0.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/41545.html
摘要:再調(diào)用個(gè)絕對(duì)值內(nèi)置函數(shù)來(lái)加深影響心急吃不了熱豆腐啊有且僅能傳入一個(gè)參數(shù),傳入不符合數(shù)量的參數(shù)就會(huì)報(bào)錯(cuò)誤傳入的參數(shù)數(shù)量是沒錯(cuò)了,但傳入錯(cuò)誤的參數(shù)類型也是會(huì)死的很慘的。 調(diào)用函數(shù) 干貨:Python官網(wǎng)查看函數(shù)幫助信息 http://docs.python.org/3/libr... showImg(https://segmentfault.com/img/bV71Kn?w=348&h=8...
摘要:理解了輸入輸出,就可以簡(jiǎn)單的打印有意義的程序了比如打印先輸入回車輸入或其它內(nèi)容,存入變量輸入當(dāng)然為了用戶體驗(yàn)更好,可以適當(dāng)?shù)奶砑右恍┨崾拘畔?shù)據(jù)類型和變量整數(shù)常用十六進(jìn)制表示與數(shù)學(xué)上表示方法一樣等。常量不能變的量,通常用大寫字母表示 1、輸出函數(shù):Print() 接受多個(gè)字符串時(shí)用逗號(hào)隔開(相當(dāng)于空格),就可連成一串輸出。 showImg(https://segmentfault.co...
摘要:本文是通過廖雪峰的網(wǎng)站學(xué)習(xí)而整理的真的是很好的教程,省得我花錢買書了,然后我沒有去再整理總結(jié)語(yǔ)法,而是直接通過寫出代碼段來(lái)體現(xiàn)自己的學(xué)習(xí),也方便以后的快速?gòu)?fù)習(xí)回顧。 不想再像以前那樣,什么都從頭開始學(xué)習(xí)語(yǔ)法、總結(jié)語(yǔ)法,這樣反而會(huì)過分糾結(jié)于語(yǔ)法,耽誤了開發(fā),畢竟語(yǔ)言的主要屬性是工具,次要的屬性是語(yǔ)言本身。 所以還是先熟練使用語(yǔ)言去進(jìn)行開發(fā),等足夠熟悉了,再去研究語(yǔ)言本身(編譯原理……)。...
摘要:同樣的用上節(jié)講的函數(shù)獲取元素的個(gè)數(shù)記住這是獲取的是列表個(gè)數(shù)個(gè)數(shù)個(gè)數(shù)重要的事說三遍。用索引訪問每個(gè)元素的位置,索引是從開始的開始的開始的索引也是有容忍限度的超過了就會(huì)原地爆炸報(bào)錯(cuò)如果列表中元素個(gè)數(shù)賊多,想獲取后面的元素就要實(shí)行曲線救國(guó)了。 list和tuple是Python內(nèi)置的有序集合,一個(gè)是可變的,一個(gè)是不可變滴;這都不是事,主要是理解一下指向不變。 看圖說話: showImg(ht...
閱讀 1057·2021-11-18 13:23
閱讀 762·2021-11-08 13:16
閱讀 875·2021-10-11 10:58
閱讀 3523·2021-09-22 15:26
閱讀 1753·2021-09-08 10:42
閱讀 1831·2021-09-04 16:45
閱讀 1746·2019-08-30 15:54
閱讀 2577·2019-08-30 13:45