您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)Python 中可迭代對象和迭代器生成器的區(qū)別是什么,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
生成器是一種特殊的迭代器,生成器自動實(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è)資訊頻道。
免責(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)容。