python--4、 可迭代對象、迭代器、產生器,python--4產生器
可迭代對象 iterable
可直接作用於for迴圈的對象統稱為可迭代對象。
有 list、 dict、tuple、set、str等資料類型,還有 generator(包括產生器和帶yield的generator function)。包括了有序和無序對象。
要判斷一個對象是否為iterable對象。方法如下:
from collections import Iterable
isinstance([],Iterable)
迭代器 iterator
迭代,即一些事要重複好多次,就像在迴圈中做的那樣。
一個對象是否可迭代,全都取決於這個對象是否有__iter__方法,只要該對象實現了__iter__方法,調用對象的__iter__方法,就回返回一個迭代器,這個迭代器一定具有next方法(調用這個方法時不需要任何參數),在調用這個迭代器的next方法時,迭代器就回返回它的下一個值,當迭代器中沒有值可以返回了,就回拋出一個名為StopIteration的異常,停止迭代。
準確的說,一個實現了__iter__方法的對象是可迭代的,一個實現了next方法的對象則是迭代器。
例如檔案既有iter方法又有next方法,是可迭代對象也是迭代器,為什麼還要iter方法呢。iter方法要使所有可迭代對象產生統一的迭代器格式。
每次調用next()方法的時候會做兩件事:
1、為下一次調用next()方法修改狀態
2、為當前這次調用產生返回結果
特性:無法復原,只能前進,不能後退。只能不斷通過next()函數擷取下一個資料,有需要的時候才產生值返回,沒調用的時候就處於休眠狀態等待下一次調用。
for迴圈就是這樣工作的,for迴圈在迴圈一個對象的時候,會調用這個對象的__iter__方法,得到迭代器,然後在調用這個迭代器的next方法,去獲得這個迭代器中包涵的每個值。
要判斷一個對象是否為iterator對象。方法如下:
from collections import Iterator
isinstance((x for x in range(9)),Iterator)
迭代器與列表的區別
迭代器是惰性的,一個接著一個的擷取值,只能往後取值。但無法擷取迭代器的長度。
列表,一次性擷取所有的值。如果有很多值,列表就會佔用太多的記憶體。
例:
class test_class:
def __init__(self,start_num,stop_num):
self.start_num = start_num
self.stop_num = stop_num
def next(self):
if self.start_num < self.stop_num:
self.start_num += 1
return self.start_num
def __iter__(self):
return self
test_obj = test_class(0,3)
print test_obj.next()
>>>1
print test_obj.next()
>>>2
print test_obj.next()
>>>3
產生器
一種特殊的迭代器。(用普通函數文法定義的迭代器)
產生器的兩種表達形式:
函數式產生器:使用yield關鍵字每次返回一個結果,一個函數中可以出現多個yield。函數之中每一個yield都會返回一個結果。每執行一個yield後,函數都會變成“掛起”(暫停)狀態,下次再調用時,會從上次掛起的位置繼續向下執行。
產生器運算式:使用類似於列表推導式的方法,但返回的結果不再是一個列表,而是一個產生器。
例: (i for i in range(5))
可以作用於for迴圈,也可以被next()函數不斷調用並返回下一個值,只到最後拋出stopiteration錯誤表示無法繼續返回下一個值。
總結:
可用於for迴圈的對象都是iterable類型,
可用於next()函數的對象都是iterator類型,
產生器都是iterator對象,但list、dict、str等雖然是iterable,卻不是iterator。
可以使用iter()函數可以把list等iterable變成iterator。