日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

怎么确定迭代器后面还有至少两个值_如何理解Python中的可迭代对象、迭代器和生成器

發(fā)布時(shí)間:2025/3/20 python 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 怎么确定迭代器后面还有至少两个值_如何理解Python中的可迭代对象、迭代器和生成器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

▍前言

在討論可迭代對(duì)象、迭代器和生成器之前,先說明一下迭代器模式(iterator pattern),維基百科這么解釋:

迭代器是一種最簡(jiǎn)單也最常見的設(shè)計(jì)模式。它可以讓用戶透過特定的接口巡訪容器中的每一個(gè)元素而不用了解底層的實(shí)現(xiàn)。

迭代是數(shù)據(jù)處理的基石。當(dāng)內(nèi)存中放不下數(shù)據(jù)集時(shí),我們要找到一種惰性獲取數(shù)據(jù)的方式,即按需一次獲取一個(gè)數(shù)據(jù)項(xiàng),這就是迭代器模式。▍序列可迭代的原因:iter函數(shù)
我們都知道序列是可迭代的。當(dāng)解釋器需要迭代對(duì)象x時(shí),會(huì)自動(dòng)調(diào)用iter(x)。
內(nèi)置的iter函數(shù)有以下作用:

  • 檢查對(duì)象是否實(shí)現(xiàn)了__iter__方法,如果實(shí)現(xiàn)了就調(diào)用它,獲得一個(gè)迭代器。
  • 如果沒有實(shí)現(xiàn)__iter__方法,但是實(shí)現(xiàn)了__getitem__方法,python會(huì)創(chuàng)建一個(gè)迭代器,嘗試按順序(從索引0開始)獲取元素。
  • 如果嘗試失敗,python會(huì)拋出`TypeError`異常,通常會(huì)提示"C object is not iterable",其中C是目標(biāo)對(duì)象所屬的類。

截止到Python3.6,基本上所有的Python序列也都實(shí)現(xiàn)了__getitem__方法,這是保證任何序列都可迭代的原因。當(dāng)然標(biāo)準(zhǔn)的序列也都實(shí)現(xiàn)了__iter__方法,之所以對(duì)__getitem__也可以創(chuàng)建迭代器是為了向后兼容,未來可能不在這么做。
但是,從Python3.4開始,檢查x能否迭代,最準(zhǔn)確的方法是調(diào)用iter(x)函數(shù),如果不可迭代,再處理TypeError異常。

▍可迭代對(duì)象與迭代器關(guān)系

使用iter內(nèi)置函數(shù)可以獲取迭代器對(duì)象。也就是說,如果一個(gè)對(duì)象實(shí)現(xiàn)了能返回迭代器的__iter__方法,那么對(duì)象就是可迭代的,序列都可以迭代;實(shí)現(xiàn)了__getitem__方法,而且其參數(shù)是從零開始的索引,這種對(duì)象也是可迭代的。

因此可以明確可迭代對(duì)象和迭代器之間的關(guān)系:Python從可迭代的對(duì)象中獲取迭代器。

標(biāo)準(zhǔn)的迭代器接口有兩個(gè)方法,即:

  • __next__:返回下一個(gè)可用元素,如果沒有元素,拋出StopIteration異常
  • __iter__:返回self,以便在應(yīng)該使用可迭代對(duì)象的地方使用迭代器,比如for循環(huán)中。

因?yàn)榈髦恍鑏_next__和__iter__兩個(gè)方法,所以除了調(diào)用next()方法,以及捕獲StopIteration異常之外,沒有辦法檢查是否還有遺留的元素。此外,也沒有辦法還原迭代器。如果想再次迭代,那就要調(diào)用iter(…),傳入之前構(gòu)建迭代器的可迭代對(duì)象。

構(gòu)建可迭代對(duì)象和迭代器時(shí)經(jīng)常會(huì)出現(xiàn)錯(cuò)誤,原因是混淆了兩者。要知道,可迭代的對(duì)象有個(gè)__iter__方法,調(diào)用該方法每次都實(shí)例化一個(gè)新的迭代器;而迭代器要實(shí)現(xiàn)__next__方法,返回單個(gè)元素,此外還要實(shí)現(xiàn)__iter__方法,返回迭代器本身(self),如圖。因此,迭代器可以迭代,但是可迭代的對(duì)象不是迭代器。

需要注意的是:

可迭代的對(duì)象必須實(shí)現(xiàn)__iter__方法,但不能實(shí)現(xiàn)__next__方法。另一方面,迭代器應(yīng)該一直可以迭代,迭代器的__iter__方法應(yīng)該返回自身。雖然可迭代對(duì)象和迭代器都有__iter__方法,但是兩者的功能不一樣,再次強(qiáng)調(diào)一下,可迭代對(duì)象的__iter__用于實(shí)例化一個(gè)迭代器對(duì)象,而迭代器中的__iter__用于返回迭代器本身,與__next__共同完成迭代器的迭代作用。?

▍生成器?

在Python中創(chuàng)建迭代器最方便的方法是使用生成器。生成器也是迭代器。生成器的語法類似于函數(shù),但是不返回值。為了顯示序列中的每一個(gè)元素,會(huì)使用yield語句。只要Python函數(shù)的定義體中有yield關(guān)鍵字,該函數(shù)就是生成器函數(shù)。調(diào)用生成器函數(shù)時(shí),會(huì)返回一個(gè)生成器對(duì)象。

獲取生成器通常有兩種方式,生成器函數(shù)和生成器表達(dá)式。

生成器函數(shù)

def gen_123(): # 只要Python代碼中包含yield,該函數(shù)就是生成器函數(shù)yield 1 #生成器函數(shù)的定義體中通常都有循環(huán),不過這不是必要條件;此處重復(fù)使用了3次yieldyield 2yield 3 ? if __name__ == '__main__':print(gen_123) # 可以看出gen_123是函數(shù)對(duì)象# <function gen_123 at 0x10be19>print(gen_123()) # 函數(shù)調(diào)用時(shí)返回的是一個(gè)生成器對(duì)象# <generator object gen_123 at 0x10be31> ?for i in gen_123(): # 生成器是迭代器,會(huì)生成傳給yield關(guān)鍵字的表達(dá)式的值print(i) # 1# 2# 3 ?g = gen_123() # 為了仔細(xì)檢查,把生成器對(duì)象賦值給gprint(next(g)) # 1print(next(g)) # 2print(next(g)) # 3print(next(g)) # 生成器函數(shù)的定義體執(zhí)行完畢后,生成器對(duì)象會(huì)拋出異常。 # Traceback (most recent call last): # File "test.py", line 17, in <module> # print(next(g)) # StopIteration
  • 只要Python代碼中包含yield,該函數(shù)就是生成器函數(shù)
  • 生成器函數(shù)的定義體中通常都有循環(huán),不過這不是必要條件;此處重復(fù)使用了3次yield
  • 可以看出gen_123是函數(shù)對(duì)象
  • 函數(shù)調(diào)用時(shí)返回的是一個(gè)生成器對(duì)象
  • 生成器是迭代器,會(huì)生成傳給yield關(guān)鍵字的表達(dá)式的值
  • 為了仔細(xì)檢查,把生成器對(duì)象賦值給g
  • 因?yàn)間是迭代器,所以調(diào)用next(g)會(huì)獲取yield生成的下一個(gè)元素
  • 生成器函數(shù)的定義體執(zhí)行完畢后,生成器對(duì)象會(huì)拋出異常。

生成器表達(dá)式

簡(jiǎn)單的生成器函數(shù),可以替換成生成器表達(dá)式。生成器表達(dá)式可以理解為列表推導(dǎo)的惰性版本:不會(huì)迫切的構(gòu)建列表,而是返回一個(gè)生成器,按需惰性生成元素。也就是說,如果列表推導(dǎo)是制造工廠的列表,那么生成器表達(dá)式就是制造生成器的工廠。如下演示了一個(gè)簡(jiǎn)單的生成器表達(dá)式,并且與列表推導(dǎo)做了對(duì)比。

In [1]: def gen_AB(): # 1...: print('start') ...: yield 'A' ...: print('continue')...: yield 'B' ...: print('end.') ...: ? In [2]: res1 = [x*3 for x in gen_AB()] # 2 start continue end. ? In [3]: for i in res1(): # 3...: print('-->', i) ...: AAA BBB ? In [4]: res2 = (x*3 for x in gen_AB()) # 4 ? In [5]: res2 # 5 <generator object <genexpr> at 0x106a07620> ? In [6]: for i in res2(): # 6...: print('-->', i)...: start --> A continue --> B end.
  • #1-創(chuàng)建gen_AB函數(shù)
  • #2-列表推到迫切的迭代gen_AB()函數(shù)生成的生成器對(duì)象產(chǎn)出的元素:’A’和’B’。注意。下面輸出的是start、continue、end.。
  • #3-for循環(huán)迭代列表推導(dǎo)生成的res1列表
  • #4-把生成器表達(dá)式返回的值賦值給res2。只需調(diào)用gen_AB()函數(shù),雖然調(diào)用時(shí)會(huì)返回一個(gè)生成器,但是這里并不使用。
  • #5-可以看出res2是一個(gè)生成器對(duì)象。
  • #6-只有for循環(huán)迭代res2時(shí),gen_AB函數(shù)的定義體才會(huì)真正執(zhí)行。for循環(huán)每次迭代時(shí)會(huì)隱式調(diào)用next(res2),前進(jìn)到gen_AB函數(shù)中的下一個(gè)yield語句。注意,gen_AB函數(shù)的輸出與for循環(huán)中print函數(shù)的輸出夾雜在一起。

生成器表達(dá)式是創(chuàng)建生成器的簡(jiǎn)潔句法,這樣無需定義函數(shù)再調(diào)用。不過,生成器函數(shù)靈活的多,可以使用多個(gè)語句實(shí)現(xiàn)復(fù)雜的邏輯,也可以作為協(xié)程(后面有機(jī)會(huì)講到)使用。遇到簡(jiǎn)單的情況時(shí),可以使用生成器表達(dá)式,因?yàn)檫@樣掃一眼就知道代碼的作用。其實(shí)選擇那種句法很容易判斷:如果生成器表達(dá)式需要分行寫,傾向于定義成生成器函數(shù),以便提高可讀性;此外生成器函數(shù)有名稱,因此可以重用。

a = (i for i in range(10)) '__next__' in dir(a) # True '__iter__' in dir(a) # True

以上可以看出,生成器也是一種迭代器!

前面我們提到了惰性計(jì)算。其實(shí),我們有時(shí)候使用生成器而不是傳統(tǒng)的函數(shù)時(shí),正是因?yàn)槎栊杂?jì)算有好處---只計(jì)算需要的數(shù)據(jù),并且整個(gè)系列不需要一次性全部駐留在內(nèi)存中。事實(shí)上,生成器完全可以有效的生產(chǎn)數(shù)值的無限序列,舉一個(gè)例子,斐波那契數(shù)列是一個(gè)經(jīng)典的無限數(shù)字序列,下面用生成器可以產(chǎn)生這個(gè)無窮級(jí)數(shù):

def fibonacci():a = 0b = 1while True:yield afuture = a + ba = bb = future

以上!

總結(jié)

以上是生活随笔為你收集整理的怎么确定迭代器后面还有至少两个值_如何理解Python中的可迭代对象、迭代器和生成器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 骚虎视频在线观看 | 日韩在线激情视频 | 午夜福利理论片在线观看 | 一区二区三区四区视频 | 亚洲av无码国产在丝袜线观看 | 在线艹 | 亚洲女同av | 禁果av一区二区三区 | 久久精工是国产品牌吗 | 观看av | 欧美激情国产日韩精品一区18 | 欧洲丰满少妇做爰 | 国产精品久草 | 五十路在线 | 4438x全国最大成人网 | 99日韩 | 欧美成人福利 | 欧美日韩在线免费视频 | 欧美 日韩 国产 成人 在线 91 | 人人澡人人澡人人澡 | 国产人人爱 | 国产精品视频观看 | 看了下面会湿的视频 | 亚洲精品视频中文字幕 | 免费的一级黄色片 | 国产女大学生av | 国产网站一区 | 午夜写真片福利电影网 | 91人妻一区二区 | 91精品国产99久久久久久 | www.三级| www.日韩| 男操女视频免费 | 92av视频| 粗喘呻吟撞击猛烈疯狂 | 精品无码人妻一区二区三区 | 国产欧美精品国产国产专区 | 亚洲4p | 亚洲午夜影视 | 欧美专区在线观看 | 久久久69| 国产成人免费看一级大黄 | 日韩欧美黄色片 | 在线免费视频一区 | 亚洲一区在线看 | 草av在线| 国产精品久久久久久无人区 | 自拍第二页 | 制服中文字幕 | 日韩av一 | www.国产三级| 天天插美女 | 中文字幕在线二区 | 女女同性女同一区二区三区按摩 | 四虎在线免费观看 | 91jk制服白丝超短裙大长腿 | 国产精品扒开腿做爽爽爽男男 | 成年人免费在线视频 | 亚洲高清毛片一区二区 | 爱情岛论坛亚洲入口 | 欧美高清性 | 国产污网站 | 国产一区视频在线 | 天天操网| 亚洲欧美另类激情 | 美女张开腿让男人操 | 亚洲av午夜精品一区二区三区 | 欧美精品第二页 | 欧美精品亚洲一区 | 亚洲s码欧洲m码国产av | av在线播放观看 | 黄页在线播放 | 3d欧美精品动漫xxxx无尽 | 国产美女无遮挡永久免费 | 国产69精品久久久久久 | 中国农村一级片 | 成熟的女同志hd | 成人春色影视 | 亚洲特黄毛片 | 国产亚洲欧美视频 | 加勒比在线一区 | 久色电影 | 看特级黄色片 | 天堂毛片 | 欧美性理论片在线观看片免费 | 狠狠干,狠狠操 | 成人av亚洲| 99国产精品国产精品九九 | 天天草视频| 香蕉传媒| 国产精品815.cc红桃 | 人人澡人人爱 | av一区二区三区 | 精品国产亚洲一区二区麻豆 | 久久6视频 | 日本免费三片在线播放 | 国产精品你懂的 | 91成人在线观看喷潮蘑菇 | 女王脚交玉足榨精调教 |