首頁(yè) >
熱門(mén)文章 >
大數(shù)據(jù)分析 > 大數(shù)據(jù)分析Python生成器使用教程
大數(shù)據(jù)分析Python生成器使用教程
時(shí)間:2020-09-17來(lái)源:m.5wd995.cn點(diǎn)擊量:次作者:Sissi
時(shí)間:2020-09-17點(diǎn)擊量:次作者:Sissi
Python生成器是一個(gè)功能強(qiáng)大但被誤解的工具。對(duì)于初學(xué)者來(lái)說(shuō),他們通常被認(rèn)為是一個(gè)過(guò)于困難的概念,從而產(chǎn)生了一種幻象,即初學(xué)者應(yīng)該在學(xué)習(xí)generator生成器之前一直堅(jiān)持不懈,直到他們準(zhǔn)備好為止。我認(rèn)為這種評(píng)估是不公平的,您可以比您想象的更早使用generator生成器。在大數(shù)據(jù)分析Python生成器使用教程中,我們將介紹:
1)了解生成器所需的基本術(shù)語(yǔ)
2)什么是generator生成器
3)如何創(chuàng)建自己的generator生成器
4)如何使用生成器和生成器方法
5)何時(shí)使用generator生成器
先決條件
為了充分利用大數(shù)據(jù)分析Python生成器使用教程,您應(yīng)該熟悉以下概念:
1)基本的Python數(shù)據(jù)結(jié)構(gòu)
a)什么是清單
b)什么是字典
2)功能
a)什么是功能
b)如何創(chuàng)建和使用功能
3)清單理解
a)什么是列表理解
b)如何創(chuàng)建一個(gè)簡(jiǎn)單的列表理解
基本術(shù)語(yǔ)
迭代和可迭代
迭代是一遍又一遍地重復(fù)某種過(guò)程。Python的for循環(huán)為我們提供了一種遍歷各種對(duì)象的簡(jiǎn)便方法。通常,您會(huì)遍歷一個(gè)列表,但是我們也可以遍歷其他Python對(duì)象,例如字符串和字典。
在以上每個(gè)示例中,for循環(huán)遍歷我們給出的序列。上面的代碼使用了列表,字符串和字典,但是您也可以遍歷元組和集合。在上面的每個(gè)循環(huán)中,我們print按順序顯示序列中的每個(gè)項(xiàng)目。例如,您可以確認(rèn)的順序ez_list已按照其項(xiàng)目的打印順序進(jìn)行復(fù)制。
我們將可以支持迭代的任何對(duì)象稱為可迭代。
什么定義了迭代?
可迭代支持一種稱為
迭代器協(xié)議。Iterator協(xié)議的技術(shù)定義不在大數(shù)據(jù)分析Python生成器使用教程的討論范圍之內(nèi),但是可以將其視為用于循環(huán)的一組要求for。也就是說(shuō):列表,字符串和字典都遵循Iterator協(xié)議,因此我們可以在for循環(huán)中使用它們。相反,不能遵循該協(xié)議的對(duì)象不能在for循環(huán)中使用。不遵循該協(xié)議的對(duì)象的一個(gè)??示例是整數(shù)。如果我們嘗試將整數(shù)賦予for循環(huán),Python將拋出錯(cuò)誤。
整數(shù)只是一個(gè)單數(shù),而不是一個(gè)序列。您可能會(huì)爭(zhēng)辯說(shuō),number為1,但與序列中的第一個(gè)項(xiàng)目不同。問(wèn)“ 1之后是什么?”是沒(méi)有意義的。從number因?yàn)镻ython既懂整數(shù)作為一個(gè)單一的實(shí)體。因此,可迭代的要求之一是能夠向for循環(huán)描述執(zhí)行操作的下一項(xiàng)是什么。例如,列表告訴for循環(huán),要迭代的下一項(xiàng)在當(dāng)前項(xiàng)的索引+1中(1在0之后)。因此,迭代器還必須for在停止時(shí)向循環(huán)發(fā)出信號(hào)迭代。當(dāng)我們到達(dá)序列的末尾(即列表或字符串的末尾)時(shí),通常會(huì)出現(xiàn)此信號(hào)。在大數(shù)據(jù)分析Python生成器使用教程的后面,我們將探討使某些事物可迭代的特定函數(shù),要知道的重要一點(diǎn)是,可迭代對(duì)象描述了循環(huán)應(yīng)如何for遍歷其內(nèi)容。生成器本身就是可迭代的。稍后您將看到,for循環(huán)是我們使用生成器的主要方式之一,因此循環(huán)必須能夠支持迭代。我們將深入研究如何在下一秒創(chuàng)建自己的生成器。
關(guān)鍵要點(diǎn):要了解的基本術(shù)語(yǔ)
1)迭代是在一系列項(xiàng)目上重復(fù)某些過(guò)程的想法。在Python中,迭代通常與for循環(huán)有關(guān)。
2)可迭代對(duì)象是支持迭代的對(duì)象。
3)要進(jìn)行迭代,它必須向for循環(huán)描述兩件事:
a)迭代中的下一個(gè)項(xiàng)目是什么。
b)循環(huán)何時(shí)應(yīng)停止迭代。
4)生成器是可迭代的。
基于數(shù)據(jù)的方法
為了真正探索generator生成器,我們將使用
來(lái)自Kaggle的Brewer's Friend Beer Recipes數(shù)據(jù)集。如果您想在自己的計(jì)算機(jī)上繼續(xù)學(xué)習(xí),可以在這里找到數(shù)據(jù)集。數(shù)據(jù)包含來(lái)自世界各地啤酒商的重要啤酒特性,包括啤酒樣式,酒精含量(ABV)和啤酒產(chǎn)量。就大數(shù)據(jù)分析Python生成器使用教程而言,假設(shè)我們對(duì)釀造自己的啤酒感興趣。也許我們想出售我們的啤酒,所以我們想看看其他人做了些什么,以告知我們的釀造選擇并生產(chǎn)更多流行的啤酒樣式。作者注:原始數(shù)據(jù)集中的“名稱”列包含一些凌亂的值,這些值會(huì)干擾我們的分析。您可以在此處找到可以滿足我們目的的清理版本。
generator生成器和你
如果您以前從未遇到過(guò)generator生成器,那么現(xiàn)實(shí)中最常見(jiàn)的generator生成器示例就是備用generator生成器,它會(huì)創(chuàng)建-
發(fā)電 —為您的房屋或辦公室供電。從概念上講,Python生成器從給定的序列一次生成一個(gè)值,而不是一次給出整個(gè)序列。生成器的這種一次性方式使它們與for循環(huán)如此兼容。如果這聽(tīng)起來(lái)令人困惑,請(qǐng)不要擔(dān)心太多。當(dāng)我們解釋如何創(chuàng)建生成器時(shí),它將變得更加清晰。有兩種創(chuàng)建生成器的方法。它們的語(yǔ)法不同,但是最終結(jié)果仍然是生成器。我們將通過(guò)覆蓋這些語(yǔ)法并將它們與類(lèi)似但非生成器等效的語(yǔ)法進(jìn)行比較,來(lái)教授這些概念。
1)生成器函數(shù)與常規(guī)函數(shù)
2)生成器表達(dá)式與列表理解
generator生成器功能
生成器函數(shù)就像常規(guī)函數(shù)一樣,但是有一個(gè)關(guān)鍵的區(qū)別:
yield關(guān)鍵字替換return。
上面的兩個(gè)函數(shù)執(zhí)行完全相同的操作(返回/產(chǎn)生相同的字符串)。但是,如果您嘗試檢查生成器功能,它將與常規(guī)功能顯示的內(nèi)容不匹配。
調(diào)用常規(guī)函數(shù)會(huì)告訴Python返回該函數(shù)在我們代碼中的位置,在代碼塊中執(zhí)行代碼,然后返回結(jié)果。為了使生成器函數(shù)產(chǎn)生其值,您需要將其傳遞給
next()功能。next()是一個(gè)特殊的函數(shù),詢問(wèn)“迭代中的下一個(gè)項(xiàng)目是什么?” 實(shí)際上,next()是運(yùn)行for循環(huán)時(shí)調(diào)用的精確函數(shù)!列表,字典,字符串等都實(shí)現(xiàn)了next(),因此這就是為什么您可以首先將它們合并到循環(huán)中的原因。
注意,由于函數(shù)本身就是生成器,因此必須在生成器函數(shù)中加上括號(hào)。僅提供函數(shù)名稱會(huì)引發(fā)錯(cuò)誤,因?yàn)槟鷩L試提供
next()函數(shù)名稱。不出所料,yield一旦調(diào)用next()函數(shù),生成器函數(shù)將為“ a” 。此示例不能完全代表生成器的用途。請(qǐng)記住,生成器會(huì)生成一個(gè)值流,因此,yield單個(gè)值實(shí)際上并沒(méi)有資格作為流。為此,我們實(shí)際上可以將多個(gè)yield語(yǔ)句放入生成器函數(shù)中。這些yield語(yǔ)句構(gòu)成了生成器將輸出的順序。我們將創(chuàng)建一個(gè)生成器并將其綁定到一個(gè)varible mg。然后,如果我們繼續(xù)mg進(jìn)入next(),我們將進(jìn)入下一個(gè)yield。如果我們繼續(xù)前進(jìn),將被告知StopIteration錯(cuò)誤,告知生成器沒(méi)有其他值可提供。該StopIteration錯(cuò)誤實(shí)際上是一個(gè)如何for 循環(huán)知道何時(shí)停止迭代。
分配
multi_generate到mg在使用generator生成器功能的關(guān)鍵步驟。將生成器綁定到mg允許我們創(chuàng)建可以參考的生成器的單個(gè)實(shí)例。我們可以繼續(xù)傳遞mg到next()并獲得與其他yield語(yǔ)句。觀察如果我們繼續(xù)嘗試自己傳遞下去會(huì)發(fā)生什么multi_generate。
容易將生成器視為僅等待一個(gè)命令和一個(gè)命令的機(jī)器:
next()。調(diào)用next()生成器后,它將按其持有的順序分配下一個(gè)值。否則,您將無(wú)法使用生成器執(zhí)行其他任何操作。下圖將我們的generator生成器表示為一臺(tái)簡(jiǎn)單的機(jī)器。
我們繼續(xù)得到第一條yield陳述的結(jié)果。其背后的原因是微妙的。當(dāng)我們將生成器函數(shù)本身傳遞給時(shí)next(),Python會(huì)假定您正在向其中傳遞一個(gè)新實(shí)例multi_generate,因此它將始終為您提供第一個(gè)yield結(jié)果。通過(guò)將生成器綁定到變量,Python知道在將其傳遞給時(shí),您正在嘗試對(duì)同一件事采取行動(dòng)next()。我們注意到,隨著我們不斷傳遞mg下一個(gè),我們得到了其他yield結(jié)果。僅當(dāng)生成器以某種方式記住其上次執(zhí)行的操作時(shí),這才有可能。該存儲(chǔ)器是生成器功能與常規(guī)功能的區(qū)別!使用函數(shù)后,這是一項(xiàng)一勞永逸的交易。一旦您return該函數(shù)的值。生成器將保留yield值直到輸出。這帶給我們generator生成器的另一個(gè)重要特性。一旦完成對(duì)它們的遍歷,就不能再使用它們了。一旦我們了解了中的所有三個(gè)yield值mg,便無(wú)法再為我們提供任何東西。我們必須存儲(chǔ)multi_generate生成器的另一個(gè)實(shí)例,以next()再次開(kāi)始詢問(wèn)它的語(yǔ)句。我們的數(shù)據(jù)尚未被讀取,因此讓我們使用生成器函數(shù)來(lái)完成。數(shù)據(jù)稱為recipeData.csv,并且包含在CSV文件中。我們將使用該open()函數(shù)使我們能夠讀取它,并且我們將開(kāi)始使用該next()函數(shù)來(lái)讀取CSV的前幾行。
我們將慢慢剖析上面的代碼:
1)我們已指定dataGenerator生成器作為生成器函數(shù),它將逐行分配CSV文件。該函數(shù)在中包含文件名file,這使我們能夠使用該open()函數(shù)讀取文件。
2)雖然我們討論了可以迭代列表和字典之類(lèi)的Python對(duì)象,但是我們也可以迭代文件open()。
3)該encoding通知的Python應(yīng)該期望看到什么樣的角色; ISO-8859-1特別是指Latin-1。
4)該for循環(huán)將在CSV文件的第一行,啟動(dòng)yield該行,然后保存當(dāng)前發(fā)生在閱讀文件,直到生成函數(shù)被再次調(diào)用。
如果要在自己的計(jì)算機(jī)上跟蹤數(shù)據(jù),則需要更換
file以及計(jì)算機(jī)上文件所在位置的確切路徑。這將使Python可以在需要時(shí)找到open()它。
一旦我們創(chuàng)建了一個(gè)
beerDataGenerator生成器在中beer,我們可以開(kāi)始將其傳遞next()來(lái)查看數(shù)據(jù)本身。如CSV文件所建議的,這些列用逗號(hào)分隔。此外,每行以結(jié)束\n,表示換行。我們發(fā)現(xiàn),其中的第一項(xiàng)recipeData.csv是列名列表,第一行描述了美味的香草奶油啤酒。
自我施加的限制
您可能會(huì)問(wèn):“我們可以將數(shù)據(jù)存儲(chǔ)在列表理解中!為什么要跳一個(gè)額外的箍并使用generator生成器?” 作為程序員,您可能會(huì)遇到
大數(shù)據(jù)。這是一個(gè)模糊的術(shù)語(yǔ),因此在這里我們不會(huì)深入研究各種大數(shù)據(jù)定義??梢哉f(shuō)任何大數(shù)據(jù)文件太大分配給變量。我們的數(shù)據(jù)文件不符合大數(shù)據(jù)的條件,但是我們?nèi)匀豢梢酝ㄟ^(guò)限制自己來(lái)重新創(chuàng)建這個(gè)難題來(lái)學(xué)到很多東西?,F(xiàn)在,我們假定啤酒數(shù)據(jù)量太大,以至于我們無(wú)法將所有數(shù)據(jù)存儲(chǔ)在列表中。由于無(wú)法正常讀取數(shù)據(jù),因此我們不得不重新考慮我們的選擇。這就是生成器的用武之地。我們稍后將詳細(xì)解釋生成器在這里工作的原因,但是在此之前,我們可以放心,生成器功能將使我們能夠首先讀取數(shù)據(jù),盡管不是一次全部讀取。除了生成器函數(shù),我們還可以使用生成器表達(dá)式創(chuàng)建生成器。
生成器表達(dá)式
早期,我們將生成器函數(shù)與常規(guī)函數(shù)進(jìn)行了比較,因?yàn)樗鼈兙哂性S多相似的方面。對(duì)于世代表達(dá)式,我們將使用
清單理解。
lc_example是我們的列表理解力,而genex_example我們的生成器表達(dá)式則執(zhí)行幾乎相同的任務(wù)。請(qǐng)注意,兩者之間的唯一區(qū)別是生成器表達(dá)式由括號(hào)而不是括號(hào)包圍。如果我們將這些迭代器中的任何一個(gè)for循環(huán)放置,它們將產(chǎn)生相同的結(jié)果,并且將無(wú)法區(qū)分。但是,如果我們嘗試在解釋器中檢查這些變量,它們將產(chǎn)生不同的結(jié)果。
此結(jié)果類(lèi)似于我們嘗試查看常規(guī)函數(shù)和生成器函數(shù)時(shí)所看到的結(jié)果。Python還認(rèn)識(shí)到genex_example 是生成器表達(dá)式形式的生成器()。如lc_example清單所示,我們可以執(zhí)行它們支持的所有操作:索引,切片,突變等。我們無(wú)法使用生成器表達(dá)式來(lái)執(zhí)行此操作。生成器專門(mén)用于輕松地一次生成輸出,因此不支持這些操作。但是,就像列表推導(dǎo)一樣,我們可以在生成器表達(dá)式中實(shí)現(xiàn)邏輯,以在需要時(shí)形成過(guò)濾器。
實(shí)際上,我們將如何使用生成器函數(shù)或生成器表達(dá)式?jīng)]有區(qū)別。一旦有了生成器表達(dá)式,就可以調(diào)用next()在它上面開(kāi)始獲取它將產(chǎn)生的值。一旦遍歷了生成器表達(dá)式可以產(chǎn)生的所有值,就不能再使用它了。這與列表理解形成對(duì)比,列表理解可以重復(fù)使用任意數(shù)量的內(nèi)容。
我們只能使用generator生成器的想法
曾經(jīng)與他們的消費(fèi)觀念聯(lián)系在一起。回想一下,當(dāng)我們迭代某個(gè)迭代器時(shí),我們會(huì)對(duì)其中的每個(gè)值執(zhí)行一些操作。然后,我們使用這些處理后的值繼續(xù)進(jìn)行分析,這意味著通常我們可能不需要原始的迭代器。生成器完全適合這種需求,使我們能夠形成一個(gè)可以使用一次的迭代器,而不必?fù)?dān)心它在使用后會(huì)占用空間(for例如,循環(huán))。我們討論了next()從生成器獲取值的方法,但是在for循環(huán)中使用生成器通常更好。使用next()強(qiáng)制我們不得不面對(duì)StopIteration自己,但是for循環(huán)使用它來(lái)知道何時(shí)停止!
生成器表達(dá)式與函數(shù)相比的一個(gè)區(qū)別是它們的簡(jiǎn)潔性。生成器函數(shù)占用多行,而我們可以將生成器表達(dá)式放在一行中。多行本身并不是一件壞事,但是它使功能更加復(fù)雜,從而可能在以后引入錯(cuò)誤。我們將生成器函數(shù)重寫(xiě)為單行表達(dá)式,以讀取啤酒數(shù)據(jù)。這種簡(jiǎn)潔性將在大數(shù)據(jù)分析Python生成器使用教程的稍后部分派上用場(chǎng)。
關(guān)鍵要點(diǎn):generator生成器
1)生成器一次生成一個(gè)值,而不是一次提供所有值。
2)創(chuàng)建生成器有兩種方法:生成器函數(shù)和生成器表達(dá)式。
3)generator生成器功能yield,常規(guī)功能return。
4)生成器表達(dá)式需要(),列表理解使用[]。
5)您只能使用generator生成器一次。
6)有兩種從生成器獲取值的方法:next()函數(shù)和for循環(huán)。所述for環(huán)通常是優(yōu)選的方法。
7)我們可以使用生成器來(lái)讀取文件,并一次給我們一行。
生成器:動(dòng)機(jī)和用途
之前,我們討論過(guò)對(duì)自己施加限制,迫使我們使用生成器來(lái)讀取我們的數(shù)據(jù),而不是將其讀取到列表中。我們列舉了大數(shù)據(jù)的問(wèn)題以及我們無(wú)法將其全部存儲(chǔ)在一個(gè)變量中。雖然稱它為大數(shù)據(jù)問(wèn)題仍然正確,但您也可以稱它為
內(nèi)存問(wèn)題。假設(shè)您有一臺(tái)較舊的筆記本電腦,帶有大約4GB的RAM和隨機(jī)存取內(nèi)存。啤酒數(shù)據(jù)集的真實(shí)大小只有3MB,但假設(shè)我們要求全球每個(gè)人都給我們提供他們的食譜,因此數(shù)據(jù)集大約為3GB。如果我們將整個(gè)數(shù)據(jù)集讀入一個(gè)變量,則將占用超過(guò)3GB的RAM!這將使我們幾乎沒(méi)有其他操作余地,更不用說(shuō)其他類(lèi)似大小的變量了。將我們的數(shù)據(jù)存儲(chǔ)在列表中會(huì)占用大量?jī)?nèi)存,以至于我們進(jìn)行的任何分析都將花費(fèi)很長(zhǎng)時(shí)間。
懶惰和generator生成器
現(xiàn)在我們知道生成器從定義的序列中產(chǎn)生單個(gè)值,但是僅當(dāng)我們?cè)儐?wèn)next()或for循環(huán)內(nèi)時(shí)。我們稱這種懶惰的評(píng)價(jià)。生成器之所以懶惰,是因?yàn)樗鼈儍H在我們要求時(shí)才給我們帶來(lái)價(jià)值。不利的一面是,只有那個(gè)值會(huì)占用內(nèi)存。最終結(jié)果是生成器的存儲(chǔ)效率非常高,這使其成為讀取和使用大數(shù)據(jù)文件的理想選擇。一旦要求生成器的下一個(gè)值,舊值將被丟棄。一旦我們遍歷整個(gè)生成器,它也將從內(nèi)存中丟棄。
generator生成器給generator生成器供電
我們目前還沒(méi)有從啤酒數(shù)據(jù)中學(xué)到任何東西。到目前為止,我們所要做的就是獲取原始CSV文件并創(chuàng)建一個(gè)生成器,該生成器將生成CSV中的每一行,一次生成一個(gè)字符串形式。除非我們想做一些瘋狂的字符串操作,否則我們需要考慮一種將數(shù)據(jù)轉(zhuǎn)換為可讀,可用形式的方法。下面是我們代碼當(dāng)前功能的表示:從文件中輕松讀取文件,并從文件中輸出一行內(nèi)容。
generator生成器在這里再次救援!到目前為止,在大數(shù)據(jù)分析Python生成器使用教程中,我們一直在將其他結(jié)構(gòu)(特別是迭代器)傳遞給生成器,以指示要從中生成什么序列。但是,生成器本身也是迭代器-為什么我們不創(chuàng)建另一個(gè)生成器來(lái)獲取另一個(gè)生成器呢?我們的lines生成器完整地輸出了該行,因此我們將創(chuàng)建第二個(gè)生成器來(lái)為我們做一些格式化。
我們的生成器的最終結(jié)果是一個(gè)列表流,每個(gè)列表都包含CSV行中的數(shù)據(jù)。如果我們遍歷
lists,我們將能夠輕松訪問(wèn)其中的數(shù)據(jù)元素并執(zhí)行所需的分析!我們已經(jīng)有效地為我們的數(shù)據(jù)集建立了一條管道,從原始數(shù)據(jù)集開(kāi)始,并通過(guò)2個(gè)生成器將其發(fā)送,以使其成為熟悉的形式。請(qǐng)記住,生成器本身并不是列表,它們僅生成序列中的單個(gè)元素,并且僅占用該元素所需的數(shù)量。通過(guò)將生成器連接在一起,我們創(chuàng)建了一種快速,易于閱讀的方式,使我們可以讀取通常無(wú)法訪問(wèn)的數(shù)據(jù)。這種方法具有真正的力量,其重要性不可低估。在處理中間值時(shí),我們不需要?jiǎng)?chuàng)建任何臨時(shí)列表來(lái)保存中間值。在管道中增加了生成器之后,我們的代碼可能如下所示:在此管道中,每個(gè)生成器負(fù)責(zé)單個(gè)操作,該操作最終將應(yīng)用于數(shù)據(jù)集的所有行。盡管每個(gè)列表都有好處,但是在進(jìn)行任何有意義的分析之前,仍然需要解決一些小問(wèn)題。首先,我們希望采用列名,因?yàn)樗鼈儾皇菙?shù)據(jù),然后將其轉(zhuǎn)換為字典,這將使任何其他代碼都更易于閱讀。注意:如果要在自己的計(jì)算機(jī)上運(yùn)行此代碼,則必須記住,只能使用一次生成器。如果您在for循環(huán)中使用生成器來(lái)查看輸出,則需要再次運(yùn)行數(shù)據(jù)和整個(gè)管道。幸運(yùn)的是,generator生成器在這里運(yùn)行很快。
beerdicts 進(jìn)行一些簡(jiǎn)單的格式化,這使我們的管道擁有更多的功能!
這是開(kāi)始查詢我們有關(guān)未來(lái)啤酒釀造選擇的數(shù)據(jù)的好地方?,F(xiàn)在我們已經(jīng)有了生成器管道,我們可以開(kāi)始使用生成器產(chǎn)生的數(shù)據(jù)并創(chuàng)建一些見(jiàn)解。我們通常使用for循環(huán)來(lái)消耗生成器,因此我們將使用一個(gè)循環(huán)來(lái)找出最流行的自釀啤酒類(lèi)型。
此操作在數(shù)據(jù)整理和處理中無(wú)處不在,您可能之前已經(jīng)看過(guò)。這里唯一的新事物是,我們依賴于生成器生成的字典,而不是引用包含數(shù)據(jù)的列表的列表。使用生成器,我們可以像常規(guī)大小的查詢一樣從任何大數(shù)據(jù)集中進(jìn)行相同的查詢?,F(xiàn)在我們知道,美國(guó)IPA是數(shù)據(jù)集中最受歡迎的自釀啤酒,并且我們知道它們?cè)跀?shù)據(jù)中有多少個(gè)條目。我們可以嘗試弄清楚我們的啤酒應(yīng)該有多強(qiáng)。此數(shù)據(jù)包含在“ ABV”(
酒精體積)鍵。由于我們正在使用字典作為生成器流的輸出,因此為什么不添加另一個(gè)生成器來(lái)細(xì)化我們要輸出的確切值。
最后一個(gè)生成器構(gòu)成了我們管道的最后一個(gè),如下圖所示:
我們應(yīng)該特別注意sum()在abvgenerator生成器上使用的情況。sum()將接收到的所有ABV值相加并不是立即直觀的。你可能認(rèn)為的sum()作為減少generator生成器的輸出整成一個(gè)值。通過(guò)將該總和除以美國(guó)IPA整體的數(shù)量,得出平均值。我們的數(shù)據(jù)表明,按體積計(jì)算,您的平均美國(guó)IPA約為6.4%的酒精含量!我們的最后一個(gè)生成器abv采用由beerdicts輸出的字典并輸出ABV鍵,但僅如果啤酒是美國(guó)IPA。生成器表達(dá)式上的過(guò)濾器在我們的管道中形成了強(qiáng)大的工具。如果我們將每個(gè)后續(xù)生成器都視為模塊化組件,則可以將生成器換成其他具有更理想功能的生成器。如果我們想改變我們想要研究的啤酒種類(lèi)或研究另一種啤酒特性,我們唯一需要改變的就是generator生成器操作。下圖顯示了生成器管道方法的不同部分。它由您要處理的一些原始數(shù)據(jù),進(jìn)行實(shí)際處理的管道以及該管道輸出的最終消耗組成。按照此模式,您可以重新執(zhí)行我們對(duì)啤酒數(shù)據(jù)所做的操作。如果您習(xí)慣于使用列表列表并利用所有列表方法進(jìn)行分析的工作流程,那么這種新的數(shù)據(jù)整理方法可能會(huì)很奇怪。但是,數(shù)據(jù)管道是一個(gè)強(qiáng)大的概念,可以立即將其合并到您的代碼中,您應(yīng)該嘗試一下。
無(wú)限的一代
可以說(shuō),自您第一次對(duì)啤酒數(shù)據(jù)集進(jìn)行分析以來(lái)已經(jīng)過(guò)去了幾年。您利用分析中的洞察力創(chuàng)建了成功的美國(guó)IPA,您只需要感謝generator生成器。您每天生產(chǎn)數(shù)千瓶啤酒,并且需要一種分析每批次質(zhì)量的方法。您回到舊筆記本電腦啟動(dòng)Python解釋器。您開(kāi)始編寫(xiě)一個(gè)函數(shù)來(lái)計(jì)算和檢查啤酒批次的各種質(zhì)量,然后停止。您不知道要提前制作多少啤酒。按天分析批次可以為我們提供離散點(diǎn),但是如果我們想要連續(xù)數(shù)據(jù)怎么辦?常規(guī)功能在這里不起作用!他們需要一些參數(shù),并且將始終返回離散對(duì)象。您無(wú)法想象給常規(guī)函數(shù)提供數(shù)據(jù)流并返回連續(xù)的值流。但是您可以使用generator生成器!生成器非常適合此類(lèi)任務(wù)。我們已經(jīng)討論了生成器如何一次一次產(chǎn)生值直到被告知停止。如果我們從不給generator生成器停止信號(hào),它將很高興無(wú)限地產(chǎn)生這些值。請(qǐng)看下面的例子。
whileloop始終為真,因此生成器函數(shù)將始終產(chǎn)生啤酒。我們沒(méi)有做錯(cuò)任何事情,這是完全有效的代碼(盡管您實(shí)際上不想實(shí)現(xiàn))。這種“無(wú)限”的啤酒流如何適應(yīng)我們的時(shí)間表?在最初查看啤酒數(shù)據(jù)集的過(guò)程中,CSV最初是固定數(shù)量的行。如果您可以使釀造過(guò)程自動(dòng)化以將該數(shù)據(jù)輸出到類(lèi)似的CSV并不斷更新,那么運(yùn)行分析所需要做的就是再次通過(guò)生成器運(yùn)行數(shù)據(jù)!可以想象,您可以在管道中創(chuàng)建一個(gè)生成器,以捕獲不符合您期望的任何批次并實(shí)時(shí)標(biāo)記它們!不幸的是,我們沒(méi)有說(shuō)數(shù)據(jù),但是這個(gè)思想實(shí)驗(yàn)應(yīng)該為Python生成器提供另一個(gè)引人注目的用例。有了generator生成器.
關(guān)鍵要點(diǎn):generator生成器背后的動(dòng)機(jī)和用途
1)生成器具有存儲(chǔ)效率,因?yàn)樗鼈冎恍枰獮槠渖傻囊粋€(gè)值存儲(chǔ)即可。
2)生成器很懶:它們僅在明確要求時(shí)才產(chǎn)生值。
3)您可以將一個(gè)生成器的輸出饋送到另一個(gè)生成器的輸入,以形成數(shù)據(jù)管道。
4)數(shù)據(jù)管道可以模塊化并根據(jù)您的需求進(jìn)行定制。
5)生成器可用于無(wú)限生成值。
結(jié)論
生成器不必是復(fù)雜的主題,只要有時(shí)間可以理解,它們就可以在任何Python程序員的作品集中占有一席之地。即使在大數(shù)據(jù)情況下,更簡(jiǎn)單的方法也無(wú)法滿足需求,基于生成器的分析仍然非常重要。我們?cè)谶@里沒(méi)有討論很多有關(guān)生成器的信息,但是它仍然應(yīng)該為您在自己的分析生活中開(kāi)始使用它們提供良好的基礎(chǔ)。