日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

作者:Aniruddha Bhandari

翻譯:王琦

校對(duì):和中華

本文約3700字,建議閱讀10分鐘。

本文介紹了Python中的生成器和迭代器。在處理大量數(shù)據(jù)時(shí),計(jì)算機(jī)內(nèi)存可能不足,我們可以通過(guò)生成器和迭代器來(lái)解決該問(wèn)題。

迭代器:一次一個(gè)!

Python 是一種美麗的編程語(yǔ)言。我喜歡它提供的靈活性和難以置信的功能。我喜歡深入研究Python的各種細(xì)微差別,并了解它如何應(yīng)對(duì)不同的情況。

在使用Python的過(guò)程中,我了解到了一些功能,這些功能的使用與其簡(jiǎn)化的復(fù)雜度不相稱。我喜歡稱它們?yōu)镻ython中“隱藏的寶石”。很多人對(duì)此并不了解,但對(duì)于分析和數(shù)據(jù)科學(xué)專家來(lái)說(shuō),它們非常有用。

Python迭代器和生成器正好屬于這一類。它們的潛力是巨大的!

什么是Python的迭代器和生成器?(附代碼)

 

如果你曾經(jīng)在處理大量數(shù)據(jù)時(shí)遇到麻煩(誰(shuí)沒(méi)有呢?!),并且計(jì)算機(jī)內(nèi)存不足,那么你會(huì)喜歡Python中的迭代器和生成器的概念。

與其將所有數(shù)據(jù)一次性都放入內(nèi)存中,不如將它按塊處理,只處理當(dāng)時(shí)所需的數(shù)據(jù),對(duì)嗎?這將大大減少我們計(jì)算機(jī)內(nèi)存的負(fù)載。這就是迭代器和生成器的作用!

因此,讓我們仔細(xì)讀讀本文,探索Python迭代器和生成器的世界吧。

我假設(shè)你熟悉Python的基礎(chǔ)知識(shí)。如果沒(méi)有,我建議你先從下面的熱門(mén)課程學(xué)起:

Python數(shù)據(jù)科學(xué):

https://courses.analyticsvidhya.com/courses/introduction-to-data-science?utm_source=blog&utm_medium=python-iterators-and-generators

這是我們要介紹的內(nèi)容:

  • 什么是可迭代對(duì)象?
  • 什么是Python迭代器?
  • 在Python中創(chuàng)建一個(gè)迭代器
  • 熟悉Python中的生成器
  • 實(shí)現(xiàn)Python中的生成器表達(dá)式
  • 為什么你應(yīng)該使用迭代器?

什么是可迭代對(duì)象?

可迭代對(duì)象是能夠一次返回其一個(gè)成員的對(duì)象”。

通常使用for循環(huán)完成此操作。像列表、元組、集合、字典、字符串等等之類的對(duì)象被稱為可迭代對(duì)象。簡(jiǎn)而言之,任何你可以循環(huán)的對(duì)象都是可迭代對(duì)象。

我們可以使用for循環(huán)逐個(gè)地返回可迭代的元素。在這里,我們使用for循環(huán)遍歷列表的元素:

# iterables  sample = ['data science', 'business analytics', 'machine learning']  for i in sample:      print(i)
什么是Python的迭代器和生成器?(附代碼)

 

既然我們知道了什么是可迭代對(duì)象,那么實(shí)際上我們是如何遍歷這些值的?以及我們的循環(huán)如何知道何時(shí)停止?進(jìn)入到迭代器部分!

什么是Python迭代器?

迭代器是代表數(shù)據(jù)流的對(duì)象,即可迭代。它們?cè)赑ython中實(shí)現(xiàn)了迭代器協(xié)議。這是什么?

好吧,迭代器協(xié)議允許我們?cè)谝粋€(gè)可迭代對(duì)象中使用兩種方法來(lái)循環(huán)遍歷項(xiàng):__iter __()和__next __()。所有的可迭代對(duì)象和迭代器都有__iter __()方法,該方法返回一個(gè)迭代器。

迭代器跟蹤可迭代對(duì)象的當(dāng)前狀態(tài)。

但可迭代對(duì)象和迭代器不同之處在于__next __()方法只能由迭代器訪問(wèn)。這使得無(wú)論何時(shí)只要我們要求迭代器返回下一個(gè)值,迭代器就會(huì)返回下一個(gè)值。

讓我們創(chuàng)建一個(gè)簡(jiǎn)單的可迭代對(duì)象、本例中為一個(gè)列表以及使用__iter __()方法來(lái)構(gòu)造一個(gè)迭代器來(lái)了解其工作原理:

sample = ['data science', 'business analytics', 'machine learning']  # generating an iterator  it = sample.__iter__()  print(it)  # iterables do not have __next__() method  sample.__next__()  
什么是Python的迭代器和生成器?(附代碼)

 

是的,正如我所說(shuō),可迭代對(duì)象有用于創(chuàng)建迭代器的__iter __()方法,但它們沒(méi)有僅迭代器才有的__next __()方法。因此,讓我們?cè)僭囈淮危缓髧L試從列表中檢索值:

sample = ['data science', 'business analytics', 'machine learning']  # generating an iterator  it = sample.__iter__()  print(it.__next__())  print(it.__next__())  print(it.__next__()) 
什么是Python的迭代器和生成器?(附代碼)

 

完美!但等一下,我不是說(shuō)迭代器也具有__iter __()方法嗎?那是因?yàn)?strong>迭代器也是可迭代的,但反過(guò)來(lái)不成立。它們是自己的迭代器。讓我通過(guò)遍歷迭代器向你展示這個(gè)概念:

sample = ['data science', 'business analytics', 'machine learning']  it = sample.__iter__()  itit = it.__iter__()  print(type(itit))  print(itit.__next__())  print(itit.__next__())  print(itit.__next__())  
什么是Python的迭代器和生成器?(附代碼)

 

酷!但我們可以使用iter()和next()來(lái)代替__iter__()和__next__()方法,它們提供了一種更簡(jiǎn)潔的方法:

sample = ['statistics', 'linear algebra', 'probability']    # iterator  it = iter(sample)    # next values  print(next(it))  print(next(it))  print(next(it))
什么是Python的迭代器和生成器?(附代碼)

 

 

但如果我們超過(guò)了調(diào)用next()方法的限制次數(shù),該怎么辦?這會(huì)發(fā)生什么呢?

 print(next(it))  
什么是Python的迭代器和生成器?(附代碼)

 

是的,我們得到了一個(gè)錯(cuò)誤!如果我們?cè)诘竭_(dá)迭代器的末尾之后嘗試訪問(wèn)下一個(gè)值,則會(huì)引起StopIteration異常,該異常的意思是“你不能更進(jìn)一步了!”。

我們可以使用異常處理來(lái)處理此錯(cuò)誤。實(shí)際上,我們可以自己構(gòu)建一個(gè)循環(huán)來(lái)遍歷可迭代的項(xiàng):

sample = ['statistics', 'linear algebra', 'probability']  it = iter(sample)  while True:      # this will execute till an error is raised      try:          val = next(it)      # when we reach end of the list, error is raised and we break out of the loop      except StopIteration:          break      print(val) 
什么是Python的迭代器和生成器?(附代碼)

 

如果你退后一步,你會(huì)意識(shí)到,這正是for循環(huán)在底層運(yùn)行的方式。我們?cè)诖颂幨謩?dòng)循環(huán)中所做的操作,for循環(huán)會(huì)自動(dòng)執(zhí)行相同的操作。這就是為什么for循環(huán)比遍歷可迭代對(duì)象更可取,因?yàn)樗鼈儠?huì)自動(dòng)處理異常。

每當(dāng)我們迭代一個(gè)可迭代對(duì)象時(shí),for循環(huán)通過(guò)iter()知道要迭代的項(xiàng),并使用next()方法返回后續(xù)的項(xiàng)。

在Python中創(chuàng)建一個(gè)迭代器

既然我們知道了Python迭代器是如何工作的,我們可以更深入地研究并從頭開(kāi)始創(chuàng)建一個(gè)迭代器,以更好地了解其是如何湊效的。

我將創(chuàng)建一個(gè)用于打印所有偶數(shù)的簡(jiǎn)單迭代器

class Sequence():      def __init__(self):          self.num = 2      def __iter__(self):          return self      def __next__(self):          val = self.num          self.num += 2          return val 

讓我們分解一下這段Python代碼:

  • __init __()方法是類構(gòu)造函數(shù),調(diào)用類時(shí)會(huì)首先執(zhí)行該函數(shù)。它用于分配程序執(zhí)行期間類最初所需的任何值。我在這里設(shè)置num變量的初始值為2;
  • iter()和next()方法使這個(gè)類變成了迭代器;
  • iter()方法返回迭代器對(duì)象并對(duì)迭代進(jìn)行初始化。由于類對(duì)象本身是迭代器,因此它返回自身;
  • next()方法從迭代器中返回當(dāng)前值,并改變下一次調(diào)用的狀態(tài)。我們將num變量的值加2,因?yàn)槲覀冎淮蛴∨紨?shù)。

我們可以創(chuàng)建Sequence對(duì)象來(lái)遍歷Sequence類,在該對(duì)象上調(diào)用next()方法:

it = Sequence()  print(next(it))  print(next(it))  print(next(it))  print(next(it))  print(next(it)) 
什么是Python的迭代器和生成器?(附代碼)

 

我沒(méi)有寫(xiě)sequence結(jié)束的條件,因此迭代器將永遠(yuǎn)繼續(xù)返回下一個(gè)值。但我們可以使用停止條件輕松地對(duì)其進(jìn)行更新:

sample = ['statistics', 'linear algebra', 'probability']    # iterator  it = iter(sample)    # next values  print(next(it))  print(next(it))  print(next(it))

我剛剛加入了一條if語(yǔ)句,只要值超過(guò)10,該語(yǔ)句就會(huì)停止迭代:

it = Sequence()  for i in it:       print(i)
什么是Python的迭代器和生成器?(附代碼)

 

在這里,我沒(méi)有使用next()方法從迭代器返回值,而是使用了for循環(huán),該循環(huán)的工作方式與之前相同。

熟悉Python中的生成器

生成器也是迭代器,但更加優(yōu)雅。使用生成器,我們可以實(shí)現(xiàn)與迭代器相同的功能,但不必在類中編寫(xiě)iter()和next()函數(shù)。相反,我們可以使用一個(gè)簡(jiǎn)單的函數(shù)來(lái)完成與迭代器相同的任務(wù):

# fibonacci sequence using a generator   def fib():         prev, curr = 0, 1      # infinite loop      while prev<5:          value = prev          # Calculate the next number in the sequence. Using Tuple unpacking.          prev, curr = curr, prev + curr          # yield the value          yield value  

你是否注意到這個(gè)生成器函數(shù)和常規(guī)函數(shù)的不同?是的,yield關(guān)鍵字!

普通函數(shù)使用return關(guān)鍵字返回值。但是生成器函數(shù)使用yield關(guān)鍵字返回值。這就是生成器函數(shù)與常規(guī)函數(shù)不同的地方(除了這種區(qū)別,它們是完全相同的)。

yield關(guān)鍵字的工作方式類似于普通的return關(guān)鍵字,但有額外的功能:它能記住函數(shù)的狀態(tài)。因此,下次調(diào)用generator函數(shù)時(shí),它不是從頭開(kāi)始,而是從上次調(diào)用中停止的位置開(kāi)始。

讓我們看看它是如何工作的:

# generator object  gen=fib()  print(gen)  # values  print(next(gen))  print(next(gen))  print(next(gen))  print(next(gen))  print(next(gen))  
什么是Python的迭代器和生成器?(附代碼)

 

生成器屬于“生成器”類型,它是迭代器的一種特殊類型,但仍然是迭代器,因此它們也是懶惰的工作者。除非next()方法明確要求它們這樣做,否則它們不會(huì)返回任何值。

最初創(chuàng)建fib()生成器函數(shù)的對(duì)象時(shí),它會(huì)初始化prev和curr變量。現(xiàn)在,當(dāng)在對(duì)象上調(diào)用next()方法時(shí),生成器函數(shù)會(huì)計(jì)算值并返回輸出,同時(shí)記住函數(shù)的狀態(tài)。因此,下次調(diào)用next()方法時(shí),該函數(shù)將從上次停止的地方開(kāi)始,從那里繼續(xù)。

每當(dāng)使用next()方法時(shí),該函數(shù)將繼續(xù)生成值,直到prev變得大于5,這時(shí)將引起StopIteration異常,如下所示:

print(next(gen))
什么是Python的迭代器和生成器?(附代碼)

 

實(shí)現(xiàn)Python中的生成器表達(dá)式

你不必在每次執(zhí)行生成器時(shí)都編寫(xiě)函數(shù)。相反,你可以使用生成器表達(dá)式,就像列表生成式一樣。唯一的區(qū)別是,與列表生成式不同,生成器表達(dá)式包含在圓括號(hào)內(nèi),如下所示:

squared_gen = (x*x for x in range(2,5))  print(squared_gen)
什么是Python的迭代器和生成器?(附代碼)

 

但它們?nèi)匀缓軕校虼四阈枰褂胣ext()方法。但你現(xiàn)在知道使用for循環(huán)可以更好地返回值:

for i in squared_gen:      print(i) 
什么是Python的迭代器和生成器?(附代碼)

 

當(dāng)你編寫(xiě)簡(jiǎn)單的代碼時(shí),生成器表達(dá)式非常有用,因?yàn)樗鼈円鬃x、易理解。但隨著代碼變得更復(fù)雜,它們的功能會(huì)迅速變?nèi)酢T谶@種情況下,你發(fā)現(xiàn)自己會(huì)重新使用生成器函數(shù),生成器函數(shù)在編寫(xiě)更復(fù)雜的函數(shù)方面提供了更大的靈活性。

為什么你應(yīng)該使用迭代器?

一個(gè)重要的問(wèn)題:為什么要先考慮用迭代器?

我在文章開(kāi)頭提到了這一點(diǎn):之所以使用迭代器,是因?yàn)樗鼈優(yōu)槲覀児?jié)省了大量?jī)?nèi)存。這是因?yàn)榈髟谏蓵r(shí)不會(huì)計(jì)算項(xiàng),而只會(huì)在調(diào)用它們時(shí)計(jì)算。

如果我創(chuàng)建一個(gè)包含1000萬(wàn)個(gè)項(xiàng)的列表,并創(chuàng)建一個(gè)包含相同數(shù)量項(xiàng)的生成器,則它們內(nèi)存大小上的差異將令人震驚:

import sys  # list comprehension  mylist = [i for i in range(10000000)]  print('Size of list in memory',sys.getsizeof(mylist))  # generator expression  mygen = (i for i in range(10000000))  print('Size of generator in memory',sys.getsizeof(mygen)
什么是Python的迭代器和生成器?(附代碼)

 

對(duì)于相同的數(shù)量的項(xiàng),列表和生成器在內(nèi)存大小上存在巨大差異。這就是迭代器的美。

不僅如此,你可以使用迭代器逐行讀取文件中的文本,而不是一次性讀取所有內(nèi)容。這會(huì)再次為你節(jié)省大量?jī)?nèi)存,尤其是在文件很大的情況下。

在這里,讓我們使用生成器來(lái)迭代讀取文件。為此,我們可以創(chuàng)建一個(gè)簡(jiǎn)單的生成器表達(dá)式來(lái)懶惰地打開(kāi)文件,一次讀取一行:

file = "Greetings.txt"  # generator expression  lines = (line for line in open(file))  print(lines)  # print lines  print(next(lines))  print(next(lines))  print(next(lines)) 
什么是Python的迭代器和生成器?(附代碼)

 

這很棒,但對(duì)于數(shù)據(jù)科學(xué)家或分析師而言,他們最終都要在Pandas的 dataframe中處理大型數(shù)據(jù)集。當(dāng)你不得不處理龐大的數(shù)據(jù)集時(shí),也許這個(gè)數(shù)據(jù)集有幾千行數(shù)據(jù)點(diǎn)甚至更多。如果Pandas可以解決這一難題,那么數(shù)據(jù)科學(xué)家的生活將變得更加輕松。

好吧,你很幸運(yùn),因?yàn)?strong>Pandas的read_csv()(
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)有處理該問(wèn)題的chunksize參數(shù)。它使你可以按指定大小的塊來(lái)加載數(shù)據(jù),而不是將整個(gè)數(shù)據(jù)加載到內(nèi)存中。處理完一個(gè)數(shù)據(jù)塊后,可以對(duì)dataframe對(duì)象執(zhí)行next()方法來(lái)加載下一個(gè)數(shù)據(jù)塊。就這么簡(jiǎn)單!

我將讀取Black Friday數(shù)據(jù)集(
https://datahack.analyticsvidhya.com/contest/black-friday/?utm_source=blog&utm_medium=
python-iterators-and-generators),該數(shù)據(jù)集包含550,068行數(shù)據(jù),讀取時(shí)設(shè)置每塊的大小為10,這樣做只是為了演示該函數(shù)的用法:

import pandas as pd    # pandas dataframe  df = pd.read_csv('./Black Friday.csv', chunksize=10)    # print first chunk of data  next(df)
什么是Python的迭代器和生成器?(附代碼)

 

# print second chunk of data  next(df)  
什么是Python的迭代器和生成器?(附代碼)

 

很有用,不是嗎?

結(jié)語(yǔ)

我確信你現(xiàn)在已經(jīng)習(xí)慣于使用迭代器,而且一定在考慮把所有函數(shù)轉(zhuǎn)換為生成器!你開(kāi)始喜歡Python編程的強(qiáng)大之處。

你以前使用過(guò)Python迭代器和生成器嗎?或者你要與社區(qū)分享其他“隱藏的寶石”?大家可以在下方評(píng)論!

原文標(biāo)題:

What are Python Iterators and Generators? Programming Concepts Every Data Science Professional Should Know

原文鏈接:

https://www.analyticsvidhya.com/blog/2020/05/python-iterators-and-generators/

編輯:黃繼彥

校對(duì):譚佳瑤

分享到:
標(biāo)簽:迭代 Python
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定