1、匿名函數python
一、定義express
語法格式:
bash
lambda args:expressionide
args:以逗號分隔的參數列表函數
expression:用到args中各參數的表達式ui
lambda定義的代碼必須是合法的表達式,不能出現多條件語句(可以使用if的三元表達式)和非表達式,如for和while等spa
lambda的首要用途是指定短小的回調函數線程
lambda將返回一個函數而不是將函數賦值給某變量名協程
In [77]: lambda x: x+1 Out[77]: <function __main__.<lambda>> In [78]: f = lambda x: x+1 In [79]: type(f) Out[79]: function In [80]: f(1) Out[80]: 2 In [81]: f(2) Out[81]: 3 # 也能夠直接使用小括號也調用匿名函數 In [88]: lambda x: x+1 Out[88]: <function __main__.<lambda>> In [89]: (lambda x: x+1) Out[89]: <function __main__.<lambda>> In [90]: (lambda x: x+1)(3) # 第一個小括號用來改變優先級,第二個表示調用函數 Out[90]: 4
總結:ip
匿名函數使用lambda定義, lambda是一個表達式而非語句
匿名函數(lambda表達式)只能寫在一行上,全部也有人叫它單行函數
lamdba是一個單個表達式,而不是一個代碼塊
參數列表不須要使用小括號
冒號不是用來開啓新的語句塊,而是分隔參數列表和表達式
沒有return語句,最後一個表達式的值即爲返回值
def語句建立的函數將賦值給某變量名,而lambda表達式直接返回函數
lambda也支持使用默認參數,關鍵字參數,可變參數,參數解構
In [130]: (lambda : 0)() Out[130]: 0 In [131]: (lambda x: 0)(1) Out[131]: 0 In [132]: (lambda x, y: x+y)(3, 5) Out[132]: 8 In [133]: (lambda *args, **kwargs: print(args, kwargs)) (*range(3), **{str(x):x for x in range(3)}) (0, 1, 2) {'0': 0, '1': 1, '2': 2}
匿名函數經常使用於高階函數中參數傳遞參數(當此函數參數很是短小時)
In [136]: help(sorted) Help on built-in function sorted in module builtins: sorted(iterable, /, *, key=None, reverse=False) Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. (END) In [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8] In [146]: lst = [1, 3, 5, 7, 2, 4, 6, 8] In [147]: sorted(lst) Out[147]: [1, 2, 3, 4, 5, 6, 7, 8] In [148]: sorted(lst, reverse=True) Out[148]: [8, 7, 6, 5, 4, 3, 2, 1] In [149]: lst == [1, 3, 5, "x", "xxj", "j", 2] Out[149]: False In [150]: lst = [1, 3, 5, "x", "xxj", "j", 2] In [151]: sorted(lst) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-151-904d7ad462e2> in <module>() ----> 1 sorted(lst) TypeError: '<' not supported between instances of 'str' and 'int' In [152]: lst.sort() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-152-e0fe8579802d> in <module>() ----> 1 lst.sort() TypeError: '<' not supported between instances of 'str' and 'int'
2、生成器
一、生成器函數
In [161]: def g(): ...: for x in range(10): ...: yield x # 表示彈出一個值 ...: In [162]: r =g In [163]: type(r) Out[163]: function In [164]: r = g() # 此時函數已經執行完成了,函數講道理已經被銷燬了;但事實上沒有被銷燬 這是生成器函數和普通函數的區別 In [165]: type(r) Out[165]: generator In [166]: r Out[166]: <generator object g at 0x7f7c20cdc938> In [161]: def g(): ...: for x in range(10): ...: yield x ...: In [169]: next(r) Out[169]: 0 In [170]: next(r) Out[170]: 1 In [171]: next(r) Out[171]: 2 In [172]: next(r) Out[172]: 3
生成器函數的工做過程:
In [174]: def gen(): ...: print('a') ...: yield 1 ...: print('b') ...: yield 2 ...: print('c') ...: return 3 ...: In [175]: g = gen() In [176]: g Out[176]: <generator object gen at 0x7f7c20cdc620> In [177]: next(g) a Out[177]: 1 In [178]: next(g) b Out[178]: 2 In [185]: def gen(): ...: print('a') ...: yield 1 ...: print('b') ...: yield 2 ...: print('c') ...: return 3 ...: In [186]: g = gen() # 執行生成器函數的時候,函數體並無被執行 In [187]: g Out[187]: <generator object gen at 0x7f7c2025f938> In [188]: next(g) # 第一個next時,執行到第一個yield,中止執行 a Out[188]: 1 In [189]: next(g) # 第2個next時,從第1個yield以後開始執行到第2個yield,中止執行 b Out[189]: 2 In [190]: next(g) # 第3次next時,從第2個yield以後開始執行,當沒有更多yield時,拋出 StopIteration,異常的值是函數的返回值 c --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-190-5f315c5de15b> in <module>() ----> 1 next(g) StopIteration: 3 In [197]: next(g) --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-197-5f315c5de15b> in <module>() ----> 1 next(g) StopIteration: In [193]: def gen(): ...: print('a') ...: yield 1 ...: print('b') ...: yield 2 ...: print('c') ...: In [194]: g = gen() In [195]: next(g) a Out[195]: 1 In [196]: next(g) b Out[196]: 2 In [197]: next(g) c --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-197-5f315c5de15b> in <module>() ----> 1 next(g) StopIteration: # 生成器函數沒有返回值時,StopIteration也沒有值
總結:
帶yield語句的函數稱之爲生成器函數,生成器函數的返回值是生成器
生成器是特殊的迭代器
生成器函數執行的時候,不會執行函數體
當next生成器的時候,當前代碼執行到第一個yield,會彈出值,並暫停函數
當再次next生成器時,從上次暫停處開始往下執行到下一個yield
當沒有多餘的yield的時候,會拋出StopIteration異常,異常的Value是函數的返回值
生成器是惰性求值的
可用於做計數器:
In [7]: def counter(): ...: x = 0 ...: while True: ...: x += 1 ...: yield x ...: In [8]: def inc(): ...: c = counter() ...: return lambda: next(c) ...: In [9]: g = inc() In [10]: g() Out[10]: 1 In [11]: g() Out[11]: 2 In [12]: g() Out[12]: 3
節省內存:
In [14]: def bib(): ...: a = 0 ...: b = 1 ...: while True: ...: a, b = b, a+b ...: yield a ...: In [15]: g = bib() In [16]: g Out[16]: <generator object bib at 0x7fb26f6bf990> In [17]: next(g) Out[17]: 1 In [18]: next(g) Out[18]: 1 In [19]: next(g) Out[19]: 2 In [20]: next(g) Out[20]: 3 In [21]: next(g) Out[21]: 5
協程 -- 生成器的高級用法
協程運行在一個線程內,在用戶態調度;也被稱爲輕量線程
調度就是由調度器來決定哪段代碼佔用CPU時間
由系統內核調度的是內核態調度
用戶本身寫代碼實現調度器來調度是用戶態調度
非搶佔式調度