生成器; 推導式
阿新 • • 發佈:2018-08-13
con __next__ 位置 列表推導 for 取值 yield turn div
一, 生成器
1,生成器的本質就是叠代器
2,生成器的特點和叠代器一樣.取值方式和叠代器一樣(__next__(), send(): 給上一個yield傳值).
3,生成器一般由生成器函數或者生成器表達式來創建
4,其實就是手寫的叠代器
#只要函數內部包含有yield關鍵字,那麽函數名()的到的結果就是生成器,並且不會執行函數內部代碼 def func(): print(‘====>first‘) yield 1 print(‘====>second‘) yield 2 print(‘====>third‘) yield 3 print(‘====>end‘) gen= func() # 不會執行你的函數. 拿到的是生成器 print(g) # <generator object func at 0x0000000002184360> # 函數中如果有yield 這個函數就是生成器函數. 生成器函數() 獲取的是生成器. 這個時候不執行函數
# gen.__next__() 執行函數. 執行到下一個yield.
# gen.__next__() 繼續執行函數到下一個yield.
yield: 相當於return 可以返回數據.
但是yield不會徹底中斷函數. 分段執行函數.可以掛起/保存函數的運行狀態
二, 生成器函數
1, 和普通函數沒有區別. 裏面有yield的函數就是生成器函數.
2, 生成器函數在執行的時候. 默認不會執行函數體. 返回生成器
3,通過生成器的__next__()分段執行這個函數.
4, send() 給上一個yield傳值, 不能再開頭(沒有上一個yield), 最後一個yield也不可以用send()
send() 和__next__()是一樣的. 可以執行到下一個yield, 可以給上一個yield位置傳值 def func(): print("我是第一個段") a = yield 123 print(a) print("張三是第二段") b = yield 456 print(b) # ?? print("李四是第三段") c = yield 789 print(c) print("王二是最後一個段") yield 79 # 最後收尾一定是yield g = func() print(g.__next__()) # 沒有上一個yield 所以不能使用send() 開頭必須是__next__() print(g.send("煎餅果子")) print(g.send("韭菜盒子")) print(g.send("鍋包肉")) ## ??
# for i in func(): # for的內部一定有__next__()
# print(i)
#
# print(list(func())) # 內部都有__next__()
三, 推導式
1. 列表推導式 [結果 for循環 條件篩選]
2. 字典推導式 {k:v for循環 條件篩選}
3. 集合推導式 {k for循環 條件}
# 推導式: 用一句話來生成一個列表 lst = ["python"+str(j) for j in range(1,16)] print(lst)
# 100以內能被3整除的數的平方 lst = [i*i for i in range(100) if i%3==0] print(lst)
# [11,22,33,44] => {0:11,1:22,2:33} lst = [11,22,33,44] dic = {i:lst[i] for i in range(len(lst)) if i < 2} # 字典推導式就一行 print(dic)
# 集合推導式 lst = [1, 1, 4, 6,7,4,2,2] s = { el for el in lst } print(s)
四,生成器表達式
(結果 for循環 條件)
特點:
1. 惰性機制
2. 只能向前
3. 節省內存(雞蛋)
生成器函數 def func(): print(111) yield 222 yield 333 g = func() # 獲取生成器 g1 = (i for i in g) # 生成器 g2 = (i for i in g1) # 生成器 #g3 = (i for i in g2) print(list(g)) # ??? [222,333] 源頭. 從源頭把數據拿走了 print(list(g1)) # ??? [] 這裏執行的時候. 源頭已經沒有數據 print(list(g2)) # ??? [] 這裏也沒有值了
重難點:
# 求和 def add(a, b): return a + b # 生成器函數 # 0-3 def test(): for r_i in range(4): yield r_i # 0,1,2,3 g = test() # 獲取生成器 for n in [2, 10]: g = (add(n, i) for i in g) # g = add(n, i) for i in g 所有n都為最後一個元素 10 print(g) # <generator object <genexpr> at 0x0000000001DF5A40> 還是生產器 # 到最後往裏面放數據就對了 print(list(g)) # [20, 21, 22, 23] 帶數據n =10算出 n = 2不帶值 print(list(g)) # [] 從源頭把數據拿走了這裏沒有為空
生成器; 推導式