Python入门篇-生成器函数
生活随笔
收集整理的這篇文章主要介紹了
Python入门篇-生成器函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Python入門篇-生成器函數
作者:尹正杰
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
?
?
一.生成器概述
1>.生成器generator
生成器指的是生成器對象,可以由生成器表達式得到,也可以使用yield關鍵字得到一個生成器函數,調用這個函數得到一個生成器對象2>. 生成器函數
函數體中包含yield語句的函數,返回生成器對象生成器對象,是一個可迭代對象,是一個迭代器生成器對象,是延遲計算,惰性求值的包含yield語句的生成器函數生成生成器對象的時候,生成器函數的函數體不會立即執行
next(generator)會從函數的當前位置向后執行到之后碰到的第一個yield語句,會彈出值,并暫停函數執行
再次調用next函數,和上一條一樣的處理過程
沒有多余的yield語句能被執行,繼續調用next函數,會拋出StopIteration異常
3>.編寫一個生成器函數樣例
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 """ 8 關于生成器函數的相關說明: 9 10 在生成器函數中,使用多個yield語句,執行一次后會暫停執行,把yield表達式的值返回 11 12 再次執行會執行到下一個yield語句 13 14 return 語句依然可以終止函數運行,但return語句返回值不能被捕獲到 15 16 return 會導致無法繼續獲取下一個值,拋出StopIteration異常 17 18 如果函數沒有顯示的return語句,如果生成器函數執行到結尾,一樣會拋出StopIteration異常喲 19 20 """ 21 def gen(): 22 print('line 1') 23 yield 1 24 print('line 2') 25 yield 2 26 print('line 3') 27 return 3 28 29 next(gen()) 30 31 next(gen()) 32 33 g = gen() 34 35 print(next(g)) 36 print(next(g)) 37 38 # print(next(g)) #報錯:StopIteration: 3,因為已經沒有多余的yield語句啦,上面已經被調用兩次了 39 40 print(next(g, 'End')) #如果沒有元素就給個缺省值 41 42 43 44 #以上代碼執行結果如下: 45 line 1 46 line 1 47 line 1 48 1 49 line 2 50 2 51 line 3 52 End?
二.生成器應用
1>.無限循環
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 def counter(): 9 i = 0 10 while True: 11 i += 1 12 yield i 13 14 def inc(c): 15 return next(c) 16 17 c = counter() #這是一個生成器對象 18 19 print(inc(c)) 20 print(inc(c)) 21 22 23 24 #以上代碼輸出結果如下: 25 1 26 22>.計數器
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 def inc(): 8 def counter(): 9 i = 0 10 while True: 11 i += 1 12 yield i 13 c = counter() 14 return lambda : next(c) #這里返回的是匿名函數 15 16 foo = inc() 17 print(foo()) 18 print(foo()) 19 20 21 22 #以上代碼輸出結果如下: 23 1 24 23>.處理遞歸問題
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 def fib(): 9 x = 0 10 y = 1 11 while True: 12 yield y 13 x, y = y, x+y 14 15 foo = fib() 16 17 for _ in range(5): 18 print(next(foo)) 19 20 for _ in range(100): 21 next(foo) 22 23 print(next(foo)) 24 25 26 #以上代碼輸出結果如下: 27 1 28 1 29 2 30 3 31 5 32 6356306993006846248183 #!/usr/bin/env python #_*_coding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ #EMAIL:y1053419035@qq.com pre = 0 cur = 1 print(pre,cur,end=" ")def fib(n,pre=0,cur=1):pre,cur = cur,pre + curprint(cur,end=" ")if n == 2:returnfib(n-1,pre,cur)fib(106) 以上代碼改寫成遞歸方式戳我~4>.協程(coroutine)
(1)生成器的高級用法(2)比進程,線程輕量級(3)是在用戶空間調度的一種實現(4)Python3 asyncio就是協程實現,已經加入到標準庫(5)Python3.5 使用async,await關鍵字直接原生支持協程 協程調度器實現思路:有2個生成器A,Bnext(A)后,A執行到了yield語句暫停,然后去執行next(B),B執行到yield語句也暫停,然后再次調用next(A),再調用next(B),周而復始,就實現了調度的效果可以引入調度的策略來實現切換的方式(6)協程就是一種非搶占式調度?
三.yield from
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 8 def inc(): 9 for x in range(1000): 10 yield x 11 12 foo = inc() 13 print(next(foo)) 14 print(next(foo)) 15 print(next(foo)) 16 17 print("*" * 20 + "我是分割符" +"*" * 20) 18 19 """ 20 以上代碼可以使用yield from代碼改寫,等價于下的代碼: 21 """ 22 def inc(): 23 yield from range(1000) 24 25 bar = inc() 26 print(next(bar)) 27 print(next(bar)) 28 print(next(bar)) 29 30 31 32 #以上代碼輸出結果如下: 33 0 34 1 35 2 36 ********************我是分割符******************** 37 0 38 1 39 2 #!/usr/bin/env python #_*_coding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ #EMAIL:y1053419035@qq.com""" yield from是Python 3.3出現新的語法yield from iterable 是 for item in iterable: yield item 形式的語法糖"""#從可迭代對象中一個個拿元素 def counter(n):for x in range(n):yield xdef inc(n):yield from counter(n)foo = inc(10) print(next(foo)) print(next(foo))#以上代碼執行結果如下: 0 1 yield from是Python 3.3出現新的語法?
轉載于:https://www.cnblogs.com/yinzhengjie/p/10962910.html
總結
以上是生活随笔為你收集整理的Python入门篇-生成器函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle expdp/impdp e
- 下一篇: 3.28.4