python函數(shù)與生成器 Python生成器函數(shù)

Python Generator(生成器)

什么是Python Generator(生成器) ?

創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站制作、網(wǎng)站設計與策劃設計,普洱網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設10年,網(wǎng)設計領(lǐng)域的專業(yè)建站公司;建站業(yè)務涵蓋:普洱等地區(qū)。普洱做網(wǎng)站價格咨詢:13518219792

Python Generator(生成器)用于在內(nèi)存資源有限的情況下,把處理大數(shù)據(jù)的任務,分解為一段一段可以管理和處理的數(shù)據(jù)塊(chunk),建立起數(shù)據(jù)流(data pipeline),從而一步一步的解決完大數(shù)據(jù)任務的技術(shù)。例如,假設有500G的數(shù)據(jù)待處理,內(nèi)存只有32G,我們可以把數(shù)據(jù)分為200M的數(shù)據(jù)塊,然后借助Python Generator技術(shù),實現(xiàn)一邊加載數(shù)據(jù)一邊進行數(shù)據(jù)處理的效果。

生成器關(guān)鍵字yield 與 函數(shù)返回語句return的區(qū)別 :

return語句 終止函數(shù)運行并返回return語句后面的變量值;return語句后面的語句不執(zhí)行。

Python生成器可以由以下兩種方式創(chuàng)建:

Python中生成器的理解?

9.10. 生成器

Generator 是創(chuàng)建迭代器的簡單而強大的工具。它們寫起來就像是正規(guī)的函數(shù),需要返回數(shù)據(jù)的時候使用 yield 語句。每次 next() 被調(diào)用時,生成器回復它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)。以下示例演示了生成器可以很簡單的創(chuàng)建出來:

前一節(jié)中描述了基于類的迭代器,它能作的每一件事生成器也能作到。因為自動創(chuàng)建了 __iter__() 和 __next__() 方法,生成器顯得如此簡潔。

另一個關(guān)鍵的功能在于兩次執(zhí)行之間,局部變量和執(zhí)行狀態(tài)都自動的保存下來。這使函數(shù)很容易寫,而且比使用 self.index 和 self.data 之類的方式更清晰。

除了創(chuàng)建和保存程序狀態(tài)的自動方法,當發(fā)生器終結(jié)時,還會自動拋出 StopIteration 異常。綜上所述,這些功能使得編寫一個正規(guī)函數(shù)成為創(chuàng)建迭代器的最簡單方法。

Generator 是創(chuàng)建迭代器的簡單而強大的工具。它們寫起來就像是正規(guī)的函數(shù),需要返回數(shù)據(jù)的時候使用 yield 語句。每次 next() 被調(diào)用時,生成器回復它脫離的位置(它記憶語句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)。以下示例演示了生成器可以很簡單的創(chuàng)建出來:

前一節(jié)中描述了基于類的迭代器,它能作的每一件事生成器也能作到。因為自動創(chuàng)建了 __iter__() 和 __next__() 方法,生成器顯得如此簡潔。

另一個關(guān)鍵的功能在于兩次執(zhí)行之間,局部變量和執(zhí)行狀態(tài)都自動的保存下來。這使函數(shù)很容易寫,而且比使用 self.index 和 self.data 之類的方式更清晰。

除了創(chuàng)建和保存程序狀態(tài)的自動方法,當發(fā)生器終結(jié)時,還會自動拋出 StopIteration 異常。綜上所述,這些功能使得編寫一個正規(guī)函數(shù)成為創(chuàng)建迭代器的最簡單方法。

python列表推導式和生成器表達式-

列表推導式和生成器表達式以及字典推導式 通常被視為Python中函數(shù)式編程的一部分,列表推導允許您使用包含較少代碼的for循環(huán)創(chuàng)建列表。

用[] 包圍

用{} 包圍

生成器表達式允許在沒有yield關(guān)鍵字的情況下即時創(chuàng)建生成器。

語法和概念類似于列表推導的語法和概念:用()包圍

Python生成器簡介

Python 中的 yield 關(guān)鍵字鮮為人知,但是作用卻很大,正是因為有了yield,才有了Python生成器。

yield 是 Python 的關(guān)鍵字,它用于 從函數(shù)返回而不破壞其局部變量的狀態(tài) ,并且在調(diào)用該函數(shù)時,從最后一個 yield 語句開始執(zhí)行。任何包含 yield 關(guān)鍵字的函數(shù)都稱為生成器。

Python 中的 yield 關(guān)鍵字的作用類似于 Python 中的 return 語句,不同之處在于:

yield的優(yōu)點

yield的缺點

Python 可以使用 括號() 創(chuàng)建生成器

更多時候,我們使用 yield 關(guān)鍵字創(chuàng)建生成器

下面這個生成器,前4次調(diào)用它時,返回的是0-3這幾個特殊值,第5次調(diào)用它時返回一個10-20之間的隨機整數(shù)。

更多時候,生成器可以返回無限的值。

注意 generator() 函數(shù)返回的是一個生成器對象,要想獲取它的值,可以像上面那樣在迭代器中取出它的值,我們也可以顯式的調(diào)用next函數(shù)獲取值。

Python | yield Keyword - GeeksforGeeks:

閑話python 45: 淺談生成器yield

生成器似乎并不是一個經(jīng)常被開發(fā)者討論的語法,因此也就沒有它的大兄弟迭代器那么著名。大家不討論它并不是說大家都已經(jīng)對它熟悉到人盡皆知,與之相反,即使是工作多年的開發(fā)者可能對生成器的運行過程還是知之甚少。這是什么原因?qū)е碌哪??我猜想大概有以下幾點原因: (1)運行流程不同尋常,(2)日常開發(fā)不需要,(3)常常將生成器與迭代器混淆。 生成器的運行流程可以按照協(xié)程來理解,也就是說 返回中間結(jié)果,斷點繼續(xù)運行 。這與我們通常對于程序調(diào)用的理解稍有差異。這種運行模式是針對什么樣的需求呢? 一般而言,生成器是應用于大量磁盤資源的處理。 比如一個很大的文件,每次讀取一行,下一次讀取需要以上一次讀取的位置為基礎(chǔ)。下面就通過代碼演示具體看看生成器的運行機制、使用方式以及與迭代器的比較。

什么是生成器?直接用文字描述可能太過抽象,倒不如先運行一段代碼,分析這段代碼的運行流程,然后總結(jié)出自己對生成器的理解。

從以上演示可以看出,這段代碼定義了一個函數(shù),這個函數(shù)除了yield這個關(guān)鍵字之外與一般函數(shù)并沒有差異,也就是說生成器的魔法都是這個yield關(guān)鍵字引起的。 第一點,函數(shù)的返回值是一個生成器對象。 上述代碼中,直接調(diào)用這個看似普通的函數(shù),然后將返回值打印出來,發(fā)現(xiàn)返回值是一個對象,而并不是普通函數(shù)的返回值。 第二點,可以使用next對這個生成器對象進行操作 。生成器對象天然的可以被next函數(shù)調(diào)用,然后返回在yield關(guān)鍵字后面的內(nèi)容。 第三,再次調(diào)用next函數(shù)處理生成器對象,發(fā)現(xiàn)是從上次yield語句之后繼續(xù)運行,直到下一個yield語句返回。

生成器的運行流程確實詭異,下面還要演示一個生成器可以執(zhí)行的更加詭異的操作:運行過程中向函數(shù)傳參。

返回生成器和next函數(shù)操作生成器已經(jīng)并不奇怪了,但是在函數(shù)運行過程中向其傳參還是讓人驚呆了。 調(diào)用生成器的send函數(shù)傳入?yún)?shù),在函數(shù)內(nèi)使用yield語句的返回值接收,然后繼續(xù)運行直到下一個yield語句返回。 以前實現(xiàn)這種運行流程的方式是在函數(shù)中加上一個從控制臺獲取數(shù)據(jù)的指令,或者提前將參數(shù)傳入,但是現(xiàn)在不用了,send方式使得傳入的參數(shù)可以隨著讀取到的參數(shù)變化而變化。

很多的開發(fā)者比較容易混淆生成器和迭代器,而迭代器的運行過程更加符合一般的程序調(diào)用運行流程,因此從親進度和使用熟悉度而言,大家對迭代器更有好感。比如下面演示一個對迭代器使用next方法進行操作。

從以上演示來看,大家或許會認為迭代器比生成器簡單易用得太多了。不過,如果你了解迭代器的實現(xiàn)機制,可能就不會這么早下結(jié)論了。python內(nèi)置了一些已經(jīng)實現(xiàn)了的迭代器使用確實方便,但是如果需要自己去寫一個迭代器呢?下面這段代碼就帶大家見識以下迭代器的實現(xiàn)。

在python中,能被next函數(shù)操作的對象一定帶有__next__函數(shù)的實現(xiàn),而能夠被迭代的對象有必須實現(xiàn)__iter__函數(shù)。看了這么一段操作,相信大家對迭代器實現(xiàn)的繁瑣也是深有體會了,那么生成器的實現(xiàn)是不是會讓你覺得更加簡單易用呢?不過千萬別產(chǎn)生一個誤區(qū),即生成器比迭代器簡單就多用生成器。 在實際開發(fā)中,如果遇到與大量磁盤文件或者數(shù)據(jù)庫操作相關(guān)的倒是可以使用生成器。但是在其他的任務中使用生成器難免有炫技,并且使邏輯不清晰而導致可讀性下降的嫌疑。 這大概也能解釋生成器受冷落的原因。不過作為一個專業(yè)的開發(fā)者,熟悉語言特性是分內(nèi)之事。

到此,關(guān)于生成器的討論就結(jié)束了。本文的notebook版本文件在github上的cnbluegeek/notebook倉庫中共享,歡迎感興趣的朋友前往下載。

Python 函數(shù) - 返回生成器

如果函數(shù)要返回一系列結(jié)果,我們常見的方法就是將結(jié)果放到一份列表中,然后返回給調(diào)用者。比如下面的函數(shù),返回字符串中每個單詞的首字母在真?zhèn)€字符串中的索引:

運行結(jié)果:

上述的結(jié)果完全符合我們的預期,但 get_word_index 函數(shù)不夠簡潔。下面我們嘗試使用生成器來實現(xiàn):

運行結(jié)果:

改寫之后,不僅運行結(jié)果符合要求,由于不需要和 result 列表交互,函數(shù)也變得非常簡潔。下面我們就來詳細學習下生成器吧~

生成器是指使用 yield 表達式的函數(shù),調(diào)用生成器函數(shù)時,它并不會真的運行,而是會返回迭代器。每次在這個迭代器上面調(diào)用內(nèi)置的 next 函數(shù)時,迭代器就會把生成器推進到下一個 yield 表達式那里。生成器傳給 yield 的值均會由迭代器返回給調(diào)用者。

此外,如果輸入量非常大,使用列表作為返回值,那么程序就有可能耗盡內(nèi)存并崩潰。相反,使用生成器之后,則可以應對任意長度的輸入數(shù)據(jù)。

例如,下面這個生成器函數(shù)可以獲取文件中單詞的索引,而不管文件內(nèi)容多大,該函數(shù)執(zhí)行時消耗的內(nèi)存,只由單行的文本長度決定:

其中 test_generator.txt 中的內(nèi)容如下:

運行結(jié)果:

下面這句話特別重要: 生成器函數(shù)返回的迭代器,是由狀態(tài)的,及調(diào)用者不應該反復使用它 。我們那 word_index_iter 來說明:

如果想重復調(diào)用,請將其封裝成容器:

運行結(jié)果:

關(guān)于上述自定義容器的實現(xiàn)原理,我的另外一篇文章做了詳細介紹,鏈接奉上:

分享名稱:python函數(shù)與生成器 Python生成器函數(shù)
分享URL:http://www.muchs.cn/article4/hphgoe.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化商城網(wǎng)站、品牌網(wǎng)站建設、網(wǎng)頁設計公司、域名注冊、

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設