Python中「可迭代」,「迭代器」和「迭代」的最基本定義是什麼? shell
我已經閱讀了多個定義,可是我沒法肯定確切的含義,由於它仍然不會陷入。 數組
有人能夠在外行方面爲我提供3個定義的幫助嗎? 函數
上面的答案很不錯,可是正如我所見到的大多數同樣,對於像我這樣的人來講,不要過於強調區別 。 工具
一樣,人們傾向於經過在__foo__()
「 X是具備__foo__()
方法的對象」這樣的定義來得到「 Python __foo__()
」。 這樣的定義是正確的-它們基於鴨子式的哲學,可是當試圖以簡單的方式理解概念時,對方法的關注每每會介於二者之間。 測試
所以,我添加了個人版本。 spa
用天然語言 線程
在Python中, code
Iterable是一個很好的可迭代對象,簡單地說,意味着能夠在迭代中使用它,例如,使用for
循環。 怎麼樣? 經過使用迭代器 。 我會在下面解釋。 xml
...,而迭代器是一個對象,它定義了如何實際執行迭代-特別是下一個元素是什麼 。 這就是爲何它必須具備next()
方法的緣由。 對象
迭代器自己也是可迭代的,區別在於其__iter__()
方法返回相同的對象( self
),而無論其先前調用next()
是否已消耗其對象。
那麼,Python解釋器for x in obj:
語句中看到for x in obj:
時會怎麼想?
看,一個
for
循環。 看起來像是一個迭代器的工做...讓咱們獲得一個。 ...有這個obj
傢伙,讓咱們問他。「
obj
先生,您有迭代器嗎?」 (...調用iter(obj)
,它調用obj.__iter__()
,它高興地發出了一個閃亮的新迭代器_i
。)好的,那很簡單...讓咱們開始迭代。 (
x = _i.next()
...x = _i.next()
...)
因爲obj
先生在該測試中成功(經過某種方法返回了有效的迭代器),咱們用形容詞來獎勵他:您如今能夠稱他爲「可迭代的obj
先生」。
可是,在簡單的狀況下,一般不會從分別擁有Iterator和Iterable中受益。 所以,您僅定義一個對象,這也是它本身的迭代器。 (Python並不真的關心obj
發出的_i
並非那麼閃亮,而僅僅是obj
自己。)
這就是爲何在我見過的大多數示例中(以及一遍又一遍使我困惑的緣由)中,您能夠看到:
class IterableExample(object): def __iter__(self): return self def next(self): pass
代替
class Iterator(object): def next(self): pass class Iterable(object): def __iter__(self): return Iterator()
可是,在某些狀況下,能夠從使迭代器與可迭代的對象分離中受益,例如,當您但願有一行項目,但須要更多「遊標」時。 例如,當您要使用「當前」和「即將到來」的元素時,能夠爲這兩個元素使用單獨的迭代器。 或從龐大列表中提取多個線程:每一個線程均可以具備本身的迭代器以遍歷全部項目。 見@雷蒙德和@ glglgl的上述回答。
想象一下您能夠作什麼:
class SmartIterableExample(object): def create_iterator(self): # An amazingly powerful yet simple way to create arbitrary # iterator, utilizing object state (or not, if you are fan # of functional), magic and nuclear waste--no kittens hurt. pass # don't forget to add the next() method def __iter__(self): return self.create_iterator()
筆記:
我將再次重複: 迭代器不可迭代 。 迭代器不能用做for
循環中的「源」。 for
循環主要須要的是__iter__()
(該__iter__()
返回next()
)。
固然, for
並非惟一的迭代循環,所以上述內容一樣適用於某些其餘構造( while
...)。
迭代器的next()
能夠拋出StopIteration以中止迭代。 可是,它沒必要永久地迭代或使用其餘方式。
在上面的「思考過程」中, _i
實際上並不存在。 我叫這個名字。
Python 3.x有一個小的變化: next()
方法(不是內置方法)如今必須稱爲__next__()
。 是的,一直以來都是這樣。
您也能夠這樣想:可迭代擁有數據,迭代器提取下一項
免責聲明:我不是任何Python解釋器的開發人員,因此我真的不知道解釋器的想法。 上面的沉思只是我如何從Python新手的其餘解釋,實驗和實際經驗中瞭解了我對這個主題的理解。
在Python中,一切都是對象。 若是說一個對象是可迭代的,則意味着您能夠將對象做爲一個集合逐步進行(即迭代)。
例如,數組是可迭代的。 您可使用for循環遍歷它們,並從索引0到索引n,n是數組對象的長度減去1。
字典(鍵/值對,也稱爲關聯數組)也是可迭代的。 您能夠逐步瀏覽他們的鍵。
顯然,不是集合的對象是不可迭代的。 例如,布爾對象只有一個值爲True或False。 它不是可迭代的(它是一個可迭代的對象是沒有意義的)。
閱讀更多。 http://www.lepus.org.uk/ref/companion/Iterator.xml
我不知道它是否對任何人都有幫助,但我老是喜歡在腦海中形象化概念以更好地理解它們。 所以,當我有一個小兒子時,我用磚塊和白皮書形象化了迭代/迭代器的概念。
假設咱們在黑暗的房間裏,在地板上,個人兒子有磚頭。 如今,大小,顏色不一樣的磚都再也不重要了。 假設咱們有5塊這樣的磚。 能夠將這5塊磚描述爲一個對象 -假設是磚塊套件 。 使用此積木工具包,咱們能夠作不少事情–能夠先取一個,而後取第二,再取第三,能夠更改積木的位置,將第一個積木放在第二個之上。 咱們能夠用這些作不少事情。 所以,這個積木工具包是一個可迭代的對象或序列,由於咱們能夠遍歷每一個積木並對其進行處理。 咱們只能作到像個人小兒子-咱們能夠在一個時間 一個磚頭打。 因此我再次覺得本身這個套磚工具是一個可迭代的工具 。
如今請記住,咱們在黑暗的房間裏。 或幾乎是黑暗的。 問題是咱們沒有清楚地看到這些磚塊,它們是什麼顏色,什麼形狀等。所以,即便咱們想對它們作些事情(也就是遍歷它們) ,咱們也不知道究竟是什麼以及如何作,由於它是太黑了。
咱們所能作的就是接近第一個磚塊(做爲磚塊工具包的組成部分),咱們能夠放一張白色熒光紙,以便咱們瞭解第一個磚塊元素的位置。 每次咱們從工具包中取出一塊磚塊時,都會將白紙替換爲下一塊磚塊,以便可以在黑暗的房間中看到它。 這張白紙只不過是一個迭代器 。 它也是一個對象 。 可是,具備可工做和可迭代對象的元素的對象–磚塊工具包。
順便說一下,這解釋了我在IDLE中嘗試如下操做並遇到TypeError時的早期錯誤:
>>> X = [1,2,3,4,5] >>> next(X) Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> next(X) TypeError: 'list' object is not an iterator
清單X是咱們的積木工具包,但不是白紙。 我須要先找到一個迭代器:
>>> X = [1,2,3,4,5] >>> bricks_kit = [1,2,3,4,5] >>> white_piece_of_paper = iter(bricks_kit) >>> next(white_piece_of_paper) 1 >>> next(white_piece_of_paper) 2 >>>
不知道是否有幫助,可是對我有幫助。 若是有人能夠確認/糾正該概念的可視化,我將不勝感激。 這將幫助我瞭解更多信息。
iterable = [1, 2] iterator = iter(iterable) print(iterator.__next__()) print(iterator.__next__())
因此,
iterable
是一個能夠循環的對象 。 例如list,string,tuple等。
在咱們的iterable
對象上使用iter
函數將返回一個迭代器對象。
如今該迭代器對象的方法命名__next__
(在Python 3,或者只是next
在Python 2),經過它能夠訪問可迭代的每一個元素。
所以,以上代碼的輸出將是:
1個
2
在處理迭代器和迭代器以前,決定迭代器和迭代器的主要因素是順序
順序:順序是數據的收集
Iterable:Iterable是支持Iter方法的序列類型對象。
Iter方法:Iter方法將序列做爲輸入並建立一個稱爲迭代器的對象
Iterator:Iterator是調用next方法並遍歷整個序列的對象。調用next方法時,它將返回當前遍歷的對象。
例:
x=[1,2,3,4]
x是一個由數據收集組成的序列
y=iter(x)
調用iter(x)時,僅當x對象具備iter方法時才返回迭代器,不然會引起異常。若是返回iterator,則y的分配方式以下:
y=[1,2,3,4]
因爲y是迭代器,所以它支持next()方法
調用next方法時,它會一步一步返回列表的各個元素。
返回序列的最後一個元素後,若是再次調用下一個方法,則會引起StopIteration錯誤
例:
>>> y.next() 1 >>> y.next() 2 >>> y.next() 3 >>> y.next() 4 >>> y.next() StopIteration