lambda的主體是一個表達式,而不是一個代碼塊,僅僅能在lambda表達式中封裝有限的邏輯進去。若是要通俗的理解lambda表達式,能夠結合C/C++中的邏輯宏定義和內聯函數概念,lambda表達式通俗的講是起到一個函數速寫的做用,而且容許在lambda代碼塊內嵌入一個函數的定義。python
f = lambda x, y: x + y print(f(1, 2)) # 輸出: 3
from functools import reduce n = 5 out = reduce(lambda x, y : x*y, range(1, n+1)) print(out) # 輸出: 120
def foo(x): return lambda y: x + y a = foo(2) print(a(2)) # 輸出: 4
foo = lambda x: lambda y: x + y # 第一個lambda理解爲用於foo函數傳入x參數,第二個lambda至關於2.2中返回值裏的lambda表達式 a = foo(3) print(a(2)) # 輸出: 5
一般會在調用接受函數做爲參數的函數(或者類)時使用lambda表達式,好比python內置的sorted函數可接受一個函數做爲它的key參數,這個key函數用於在決定條目排序順序時計算比較鍵的值,好比:小程序
a = ['1', '3', '5', '2', '9', '7'] print(sorted(a, key=lambda s: s.casefold())) # 輸出: ['1', '2', '3', '5', '7', '9']
sorted函數並非lambda表達式的惟一用法,但倒是最廣泛的一個。數組
yield關鍵字做用的通俗理解是:定義生成器(generator)時經常使用的一個帶有return做用的關鍵字,當一個函數帶有yield關鍵字,那麼這個函數已經再也不是通俗意義上的函數,它是一個生成器(帶yield關鍵字的函數纔是真正的迭代器)。.net
下面經過小程序的解讀來講明yield關鍵字的做用與用法:code
def foo(): print('hello') while True: r = yield 1 print('r: ', r) a = foo() print(next(a)) print('-'*6) print(next(a))
輸出以下對象
hello 1 ------ r: None 1
解釋:blog
一、程序開始執行之後,由於foo函數中有yield關鍵字,因此foo函數並不會真的執行,而是先獲得一個生成器(至關於一個對象);排序
二、直到調用next方法,foo函數正式開始執行,先執行foo函數中的print方法,而後進入while循環;內存
三、程序遇到yield關鍵字,而後把yield想一想成return,return了一個1以後,程序中止,並無執行賦值給r操做,此時next(g)語句執行完成,因此輸出的前兩行(第一個是while上面的print的結果,第二個是return出的結果)是執行print(next(a))的結果;
四、打印分割線
五、又開始執行下面的print(next(a)),這個時候和上面那個差很少,不過不一樣的是,這個時候是從剛纔那個next程序中止的地方開始執行的,也就是要執行r的賦值操做,這時候要注意,這個時候賦值操做的右邊是沒有值的(由於剛纔那個是return出去了,並無給賦值操做的左邊傳參數),因此這個時候r賦值是None,因此接着下面的輸出就是r: None;
六、程序會繼續在while裏執行,又一次碰到yield,這個時候一樣return 出1,而後程序中止,print函數輸出的1就是此次return出的1。
說明:這裏的next函數是經過yield關鍵字獲得的生成器(前面咱們說了這個生成器至關於一個對象)自帶的一個方法,至關於「下一步」,next開始的地方是接着上一個next中止的地方執行的,因此調用next的時候,生成器並不會從foo函數的開始執行,而是從上一次中止的地方開始執行,在遇到下一個yield的時候結束。
下面介紹一下生成器對象中的另外一個函數:send函數
def foo(): print('hello') while True: r = yield 1 print('r: ', r) a = foo() print(next(a)) print('-'*6) print(a.send(2))
輸出以下
hello 1 ------ r: 2 1
send函數的概念:就上面的程序而言:send是發送一個參數給r的,由於上面講到,return的時候,並無把1賦值給r,下次執行的時候只好繼續執行賦值操做,只好賦值爲None了,而若是用send的話,開始執行的時候,先接着上一次(return 1以後)執行,先把2賦值給了r,而後執行next的做用,碰見下一個的yield,return出結果後結束。
爲何用這個生成器,是由於若是用List的話,會佔用更大的空間,好比取0~1000,通常咱們可能這樣寫:
for n in range(1000): a = n
這個時候range(1000)段語句就默認生成一個含有1000個數的list(也就至關於C++中定義數組時固定大小)無論你是否使用這個list,它都在那裏,佔用內存,直到python解釋器自動回收。然而使用yield組合便至關於一個動態的數據定義過程,以下:
def foo(num): while num < 10: num = num + 1 yield num for n in foo(0): print(n, end=' ') print('') ''' 輸出以下: 1 2 3 4 5 6 7 8 9 10 '''