python的遞迴函式和lambda表示式

2021-08-26 05:48:22 字數 2830 閱讀 6668

在定義乙個函式的時候,在函式內部直接或者間接的呼叫了本省這個函式,就稱為遞迴函式。

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 對...