1. 程式人生 > >生成器; 推導式

生成器; 推導式

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)) # []  從源頭把數據拿走了這裏沒有為空






生成器; 推導式