溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python 中可迭代對象和迭代器生成器的區(qū)別是什么

發(fā)布時間:2021-07-06 18:20:19 來源:億速云 閱讀:257 作者:Leah 欄目:大數(shù)據(jù)

本篇文章給大家分享的是有關(guān)Python 中可迭代對象和迭代器生成器的區(qū)別是什么,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

Python 中可迭代對象和迭代器生成器的區(qū)別是什么

 生成器是一種特殊的迭代器,生成器自動實(shí)現(xiàn)了“迭代器協(xié)議”(即__iter__和next方法),不需要再手動實(shí)現(xiàn)兩方法。

首先從字面意思來解釋Iterable和Iterator的區(qū)別
Iterable:由英文的命名規(guī)則知道,后綴是able的意思就是可怎么樣的,因此iterable就是可迭代的意思 可迭代對象。
Iterator:由英文的命名規(guī)則知道,后綴是or或者er的都是指代名詞,所以iterator的意思是迭代器。
這兩個概念之間有一個包含與被包含的關(guān)系,如果一個對象是迭代器,那么這個對象肯定是可迭代的;但是反過來,如果一個對象是可迭代的,那么這個對象不一定是迭代器。
下面我們來具體了解下可迭代對象和迭代器:
可迭代
如果給定一個list或者tuple,我們可以通過for循環(huán)來遍歷這個list或tuple,這種遍歷我們稱之為迭代,在python中,迭代是通過for……in來完成的,它不僅可以用在list或tuple上,還可以用在其他可迭代對象上,那么我們怎么知道一個對象是否可迭代呢?方法是通過collections模塊的 Iterable 類型判斷:

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整數(shù)是否可迭代
False


可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象,一共有兩類,一類是我們平時常用的python數(shù)據(jù)類型,如list,tuple,dict,set都是可迭代對象,字符串也是可迭代對象,但是整數(shù)就不是可迭代對象;另一類是generator(下面會給出簡單講解)
迭代器:
對于列表這種數(shù)據(jù)結(jié)構(gòu),里面的每一個元素我們都要在內(nèi)存中為之開辟一個空間,不管你以后是否能用到它,如果要創(chuàng)建一個包含100萬個元素的列表,但是只會用到其中幾個元素,那么這樣顯然就很浪費(fèi)內(nèi)存,所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在python中這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器:generator。
要創(chuàng)建一個一個generator,有很多種方法,最簡單的方法就是直接把一個列表生成器的[]改成()

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>


可以看到創(chuàng)建的列表是將所有的元素都輸出出來,而生成器只是生成一個對象,如果使用其中的元素,可以通過生成器的next來調(diào)用

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

next方法太費(fèi)勁,也可以通過for循環(huán)

>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
... 
0
1
4
9
16
25
36
49
64
81


以上是為后面要說的迭代器做鋪墊,下面是重點(diǎn)
生成器不但可以作用于for循環(huán),還可以被next()函數(shù)不斷調(diào)用并返回下一個值,直到最后拋出StopIteration錯誤表示無法繼續(xù)返回下一個值了。
可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator。
可以使用isinstance()判斷一個對象是否是Iterator對象

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False


生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
把list、dict、str等Iterable變成Iterator可以使用iter()函數(shù):

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True


為什么list、dict、str等數(shù)據(jù)類型不是Iterator?
這時 因?yàn)閜ython的Iterator對象表示的是一個數(shù)據(jù)流,Iterator對象可以被next()函數(shù)調(diào)用并不斷返回下一個數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時拋出StopIteration錯誤??梢园堰@個數(shù)據(jù)流看做是一個有序序列,但我們卻不能提前直到序列的長度,只能不斷通過next()函數(shù)實(shí)現(xiàn)按需計(jì)算下一個數(shù)據(jù),所以Iterator的計(jì)算是惰性的,只有在需要返回下一個數(shù)據(jù)時它才會計(jì)算。
Iterator甚至可以表示一個無限大的數(shù)據(jù)流,如全體自然數(shù),而列表是永遠(yuǎn)不可能存儲全體自然數(shù)的。
總結(jié):
凡是可作用于for循環(huán)的對象都是Iterable類型,可迭代對象;
凡是可用作next()函數(shù)的對象都是Iterator類型,它表示一個惰性計(jì)算的序列。
集合數(shù)據(jù)類型如list,dict,str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個Iterator對象

生成器的創(chuàng)建:1.使用 for 循環(huán)的生成器推導(dǎo)式。2.調(diào)用帶 yield 語句的生成器函數(shù)。

迭代器生辰器異同

一.迭代器

通過iter()方法獲得了list的迭代器對象,然后就可以通過next()方法來訪問list中的元素了。當(dāng)容器中沒有可訪問的元素后,next()方法將會拋出一個StopIteration異常終止迭代器。

二.生成器

如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器(Generator)

以上就是Python 中可迭代對象和迭代器生成器的區(qū)別是什么,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI