在定義乙個函式的時候,在函式內部直接或者間接的呼叫了本省這個函式,就稱為遞迴函式。
def test():
...return test()
這個函式直接呼叫了自身。定義了test這個函式,它的返回值是test(),就是說呼叫了test()的返回值,但是test()的值是test(),這樣來回不斷地呼叫函式,如果沒有結束條件,就是乙個死迴圈,不過也是遞迴。
def a():
...b()
...return ...
def b():
...return a()
這種在函式內部呼叫了某乙個函式,這個被呼叫的函式內部又呼叫了原函式,這樣叫間接呼叫,經常出現死迴圈,而且錯誤不好查詢。
遞迴函式一定要間接或者直接的呼叫自身。
遞迴函式一定要有邊界條件,不能無休止的遞迴。
不滿足這個邊界條件是,遞迴繼續,函式執行,
滿足這個邊界條件時,遞迴停止,函式結束。
遞迴函式的層數不宜過多,遞迴層數太多的話會引起效率問題。python對遞迴函式的深度(層數)做了限制。不過限制的層數可以手動調整。
求n的階乘,是乙個明顯的可以用遞迴函式解決的問題:
def accumlate(n, outcome=1):
if n < 2: #這裡是邊界條件,當實參n小於2時,就返回outcom
return outcome
else:
outcome *= n
return accumlate(n-1, outcome)
#這裡是迭代,如果沒到邊界條件,每次都返回此函式,
但是實參每次都改變。
還有乙個典型的可以用遞迴函式的是fibonacii sequence:
def fibnacii(n, a=1, b=1, seq=none):
if seq is none: #這麼寫是想練一練這個技巧
seq =
if n < 3: #這是邊界條件
if n == 1: #如果實參給的1,那麼就是[1],特殊情況
return [1]
else: #如果給的是2,也是特殊情況,如果直接給2,seq是
return [1,1] + seq
else:
a, b = b, a + b #和迴圈一樣的思路,三個數子a, b, a+b來回換
return fibnacii(n-1, a, b, seq)
#迭代,每次迭代n都要減1,然後把新算的a, b(其實是a+b)
函式在執行的時候,會用到呼叫棧這個資料結構。
棧,stack,特點是後進先出。棧和多執行緒有關,每乙個執行緒有乙個棧,不同的執行緒之間互不干擾。
可以把棧想象成一疊便條,以下面這個函式為例:
def main(string): #這些string都是形參,品品
print(string)
def inner(string):
print(string)
return inner(string)
呼叫這個函式,就會形成乙個呼叫棧:
main('****')
首先,把一張main()函式的便條,放在桌子上;
再壓上main()要用的資料 『****』 的便條;
再壓上print()函式的便條;
執行main的print(『****』),執行結束後撕掉。現在只剩乙個main()函式的便條。
又呼叫了inner()函式,就是再在main()函式上壓上inner()便條;
再壓上inner()要用的資料 『****』 的便條;
再壓上print()函式的便條;
執行inner的print(『****』),執行結束撕掉。現在只剩乙個main()函式的便條。
執行全部結束了,把main()函式的便條也撕掉。
往上壓便條,就叫做壓棧,撕掉便條,就叫彈出棧,比如乙個區域性變數在函式內部呼叫時建立,就是壓棧,呼叫結束後消亡,就是從棧彈出,所以在外部找不到這個區域性變數了。
棧內的一條語句和資料執行完,就彈出,然後往下走根據**壓棧-執行-彈出。
遞迴函式在建立呼叫棧時,因為是不斷地呼叫自身,所以呼叫棧會壓入很多層,所以說遞迴函式的效能很差。
python的呼叫棧有層數限制,可以更改,但最好不要更改,可以通過sys模組下的getrecursionlimit()來檢視:
import sys
print(sys.getrecursionlimit())
這個深度界限用**計數的話可能不符,因為這個函式執行,可能還需要先壓入別的函式和資料。
python中有一種函式,他沒有名字,只能寫在一行裡。也叫做匿名函式。
格式如下:
lambda 引數列表:表示式
(lambda 引數列表:表示式)(實際引數)
lambda x, y: x**2 + y**3 #這是函式的定義
fn = lambda x, y: x**2 + y**3 #,可以用識別符號來接,然後呼叫
fn(2, 3)
31(lambda x, y: x**2 + y**3)(2, 3) #也可以這麼呼叫
31
這種lambda表示式定義的函式,在高階函式中運用十分廣泛。
lambda表示式的返回值就是表示式的結果。
lambda表示式裡不能出現賦值語句。
Python3學習筆記09 匿名函式lamdba
關鍵字lambda表示匿名函式,冒號前面,面的x表示函式引數。匿名函式有個限制,就是只能由乙個表示式,不用寫return,返回值就是該表示式的結果。匿名函式有個好處,因為函式沒有名字,不必擔心函式名稱衝突。此外,匿名函式也是乙個函式物件,也可以把匿名函式賦值給乙個變數,再利用變數來呼叫該函式 f l...
python遞迴函式和匿名函式
乙個函式的內部可以呼叫其他函式。但是,如果乙個函式在內部不呼叫其他函式,而是自己本身的話,這個函式就是遞迴函式。例 def fn num if num 1 result 1else result fn num 1 num return result n int input 請輸入乙個正整數 prin...
python匿名函式和遞迴函式
匿名函式格式 lambda 引數 運算 例子 hello lambda a,b a b 匿名函式一半結合內建函式使用 max list,func func匿名函式比如 列表裡面元素是字典 就是可以 list,lambda x x 鍵 min 和max幾乎一樣 map func iterables 對...