3分鐘理清可迭代、迭代器、生成器的概念,掌握Python3中迭代器的使用方法

迭代器Iterator的特點

舉個生動例子:給馬場裏所有馬洗澡,確保每一匹馬都被洗到且只洗一次。

馬羣分別通過ListIterator兩種形式,加載到for循環中執行,我們對比看一下有什麼不同。

List

  • 所有的馬抓到澡堂子裏關起來;(先算出所有的要循環的元素,一起加載到內存)
  • 然後挨個洗澡;(順序執行)
  • 都洗完了一起放出來。(執行期間所有元素都佔着內存)

Iterator

  • 先不用管馬場裏有多少馬,確認馬場只出不進;(定義迭代器對象)
  • 每次抓一匹馬出來洗澡然後放走;(next()取出一個元素執行,每次都是用到的時候纔去計算一個元素來,所以相比list幾乎不佔內存)
  • 直到沒馬可抓。(直到執行完畢)

迭代器的省內存、局部效率高的特點一目瞭然。

另外迭代器只能遍歷一次。
for i in List 執行完畢後可以馬上重複使用for i in List再來一遍。而迭代器的for循環本質上還是next(),因此在for i in Iterator 執行完畢後,Iterator中已經沒有元素可輸出,需要重新定義迭代器,才能再執行for i in Iterator 輸出元素。

可迭代、迭代器、生成器區別

生成器是迭代器中的一種。
寫成數學表達的形式,大概可以理解爲:

可迭代Iterable

所有可以用for循環的對象。
比如listtupledictsetstrIteratorgenerator

>>> for i in 'ab':
        print(i)
a
b

迭代器Iterator

可以被next()函數調用並不斷返回下一個值的對象。
比如iter(list)iter(tuple)iter(dict)iter(set)iter(str)generator

>>> x = iter('ab')
>>> print(x)
<str_iterator object at 0x00000000025BA860>
>>> next(x)
a

注意:當next()執行到直到沒有數據時,會拋出StopIteration錯誤。
只不過通常我們都是通過for循環來迭代它,並不需要關心StopIteration的錯誤。

>>> for i in iter('ab'):
        print(i)
a
b

生成器generator

同樣可以被next()函數調用並不斷返回下一個值的對象。其實還是迭代器。
只不過是生成器是通過yield方法生成器表達式產生的。

# 方法一:yield方法。如果一個函數定義中包含yield,那麼這個函數就由普通函數變成了生成器。
>>> def geti():
>>>     for i in 'ab':
>>>         yield i
>>> x = geti()
>>> print(x)
<generator object geti at 0x0000000003C08728>
# 方法二:生成器表達式。其實就是列表生成式的[]改成(),就創建了一個生成器。
>>> y = (i for i in 'ab')
>>> print(y)
<generator object <genexpr> at 0x0000000003C49200>

需要注意的是:遇到yield回傳,下次執行,是從之前回傳斷開的地方繼續執行。
下面例子中可以看到:第二次使用next的時候,是先執行完了yield後面的語句,才進入到下一個for循環的。

>>> def geti():
>>>     for i in 'ab':
>>>         yield i
>>>         print('is',i)
>>> x = geti()
>>> print(next(x))
a
>>> print(next(x))
is a
b
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章