Python知识点进阶——生成器
生成器
? ? ? 為什么要將列表轉化為迭代器?
? ? ? 因為列表太大的話用內存太大,做成迭代器可以節省空間,用的時候再拿出部分。
? ? ? 生成器是不會把結果保存在一個系列中,而是保存生成器的狀態,在每次進行迭代時返回一個值,知道遇到StopIteration異常結束。
創建生成器
? ? ? 先看個例子
當要生成的list非常大時,會拋出異常,存儲報錯。
那怎樣生成這種巨大的list呢?
可以看出b是一個generator,也就是生成器模式
生成器的創建很簡單,將列表生成式的中括號改成小括號即可
注意:這里說的不是列表,因為列表的中括號改成小括號是元組!
如果想要生成一個內容,可用next()函數:
直到最后會拋出異常,也就是到達了生成器的末端
函數進化為生成器
將函數中的return換成yield,函數就變成了生成器。
當我們調用時,發現返回的是生成器對象。為了拿到數據,我們可以使用next()函數
不過在此之前,我們先要用一個變量去接收這個生成器對象,并且為了觀察生成器的特點,我們對函數進行修改
當我們使用next(a)對生成器操作一次時,會返回循環一次的值
也就是在yield處結束本次運行
但是它的特點就是下次使用next(a)時,接著上次的斷點繼續運行,直到下一個yield
不斷使用next(a),直到運行到生成器結尾處,會出現StopIteration異常。
使用for循環調用生成器
與next()等價的方式
send()
每次運行,除了返回下一個,還會打印出None
注意item=yield i 這句,首先執行的等號右邊,yield返回,此時,返回生成器一個對象,并且中斷
下次使用f.__next__()時候,并沒有傳內容進去,可認為yield i這整個賦值給item的為None,所以item打印出為None
為了做比較,引入send()
send()可看做next()的增強版,除了可以使用next()功能,還能傳入一個值到上次yield斷開地方的整體表達式(這里是yield i)
多任務——協程
當我們在while主程序中,先使用f1.__next__()調用生成器func1,因為func1的循環條件始終為真,所以先打印(執行裝入操作)然后遇到yield退出生成器func1,回到主程序
接著執行f2.__next__()調用生成器func2,像之前調用func1一樣,先打印(執行打包操作)然后遇到yield退出生成器func2,回到主程序。因為主程序循環條件始終為真,所以繼續像之前一樣,接著調用,如此往復。這里使用打斷來停止程序執行,不然會不斷執行下去,由于兩個生成器交替執行,很快,就像在多任務執行。
轉載于:https://www.cnblogs.com/Mayny/p/9374170.html
總結
以上是生活随笔為你收集整理的Python知识点进阶——生成器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笑起来眼睛会变色生气也会变有一头七彩的长
- 下一篇: 在杭州办狗证要多少钱啊?麻烦么?(是大狗