python生成器初步瞭解
一.生成器
生成器的本質就是迭代器 一個一個的建立物件
1.建立生成器的方式:
1.生成器函式
2.通過生成器表示式來獲取生成器
3.型別轉換
2.優點
節省記憶體 ,生成器本身就是程式碼,巨虎不佔用記憶體
3.特點
惰性機制,只能向前,不能反覆
二.生成器函式
函式中包含了yield 這個函式就是生成器函式
def func(): print("你叫xxx?") yield "alex" print("真的?") yield "真的" print("Are you sure?") yield "那叫我屌絲把" ret = func() # 拿到的是ret生成器 只是產生一個生成器並不是執行 print(ret) # 只能是列印 生成器的地址 print(ret.__next__()) # 生成器就是迭代器,用next一個一個拿 print(ret.__next__()) print(ret.__next__()) print(ret.__next__()) # 沒有下一個了就會出現 StopIteration 錯誤
1.yield
1.yield和return差不多 yield是分段執行一個函式
return是立即結束這個函式的執行
2.生成器在執行的時候返回生成器,而不是執行執行此函式
2.能向下執行的兩個條件
1.__next__ 執行到下一個yield
2.send() 執行到下一個yield,給上一個yield位置傳值.在第一次執行生成器的時候不能用send(),最後一個yield也不會傳值
def fn(): print("韭菜盒子") a = yield "西紅柿炒番茄" print("a",a) b = yield "西紅柿炒雞蛋" print("b",b) c = yield "番茄炒雞蛋" print("c",c) yield "火燒" gen = fn() # send()可以給上一個yield位置傳參 print(gen.__next__()) print(gen.send("番茄")) print(gen.send("西紅柿")) print(gen.send("雞蛋"))
3.獲取生成器資料
1.所有生成器都是迭代器都可以使用for迴圈
2.都可以使用list()函式來獲取生成器內所有的資料
4.生成器的記錄
生成器中記錄的是程式碼而不是函式的執行
當執行到__next__() 執行此空間中的程式碼,執行到yield結束
def func(): print("我的天哪 ") yield "寶寶" gen = func() # 建立生成器. 此時執行會把生成器函式中的程式碼記錄在記憶體
三.推導式
1.列表推導式 [結果 for迴圈 if]
lst = [ i**2 for i in range(1,101) if i % 2 == 0] print(lst)
2.字典推導式 {結果(k,v) for迴圈 if}
#尋找名字中帶有兩個e的⼈的名字 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] lst = [ el for name in names for el in name if el.count("e") == 2 ] print(lst)
3.集合推導式 {結果(k) for迴圈 if}
四.生成器表示式
(結果 for迴圈 if)
g = (i for i in range(10)) #一次性生成器表示式 print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) # 用完就沒了 想再次用必須再寫一次表示式
五.yield from
def func(): lst = ["衣服%s" %i for i in range(500)] yield from lst # 可以把一個可迭代物件分別進行yield返回 lst1 = ["python%s期" %i for i in range(1,19)] yield from lst1 # 只有上面的yield next完才能輪到第二個 g = func() print(g.__next__()) print(g.__next__())