python中的可迭代物件
迭代是訪問集合元素的⼀種⽅式。迭代器是⼀個可以記住遍歷的位置的物件。迭代器物件從集合的第⼀個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。
1. 可迭代物件
我們已經知道可以對list、tuple、str等型別的資料使⽤for...in...的迴圈語法從
其中依次拿到資料進⾏使⽤,我們把這樣的過程稱為遍歷,也叫迭代。
但是,是否所有的資料型別都可以放到for...in...的語句中,然後讓for...in...
每次從中取出⼀條資料供我們使⽤,即供我們迭代嗎?
>>> for i in 100: ... print(i) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable >>> # int整型不是iterable,即int整型不是可以迭代的 # 我們⾃定義⼀個容器MyList⽤來存放資料,可以通過add⽅法向其中新增資料 >>> class MyList(object) ... def__init__(self): ... self.container = [] defadd(self, item): ... self.container.append(item) >>> mylist = MyList() >>> mylist.add(1) >>> mylist.add(2 >>> mylist.add(3) |
>>> for num in mylist: ... print(num) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'MyList' object is not iterable >>> # MyList容器的物件也是不能迭代的 |
我們⾃定義了⼀個容器型別MyList,在將⼀個存放了多個數據的MyList物件
放到for...in...的語句中,發現for...in...並不能從中依次取出⼀條資料返回給我
們,也就說我們隨便封裝了⼀個可以存放多條資料的型別卻並不能被迭代使⽤。
我們把可以通過for...in...這類語句迭代讀取⼀條資料供我們使⽤的對象稱之為可迭代物件(Iterable)
兩種方法:
1.可迭代物件.__iter__()
2.iter(可迭代物件)
2. 如何判斷⼀個對象是否可以迭代
可以使⽤isinstance()判斷⼀個物件是否是 Iterable 物件:
In [50]: from collections import Iterable In [51]: isinstance([], Iterable) Out[51]: True In [52]: isinstance({}, Iterable) Out[52]: True In [53]: isinstance('abc', Iterable) Out[53]: True In [54]: isinstance(mylist, Iterable) Out[54]: False In [55]: isinstance(100, Iterable) |
Out[55]: False
3. 可迭代物件的本質
我們分析對可迭代物件進⾏迭代使⽤的過程,發現每迭代⼀次(即在for...in... 中每迴圈⼀次)都會返回對象中的下⼀條資料,⼀直向後讀取資料直到迭代了所有資料後結束。那麼,在這個過程中就應該有⼀個“⼈”去記錄每次訪問到了第⼏條資料,以便每次迭代都可以返回下⼀條資料。我們把這個能幫助
我們進⾏資料迭代的“⼈”稱為迭代器(Iterator)。
可迭代物件的本質就是可以向我們提供⼀個這樣的中間“⼈”即迭代器幫助我們對其進⾏迭代遍歷使⽤。
可迭代物件通過 __iter__⽅法向我們提供⼀個迭代器,我們在迭代⼀個可迭代對象的時候,實際上就是先獲取該對象提供的⼀個迭代器,然後通過這個迭代器來依次讀取對象中的每⼀個數據。那麼也就是說,⼀個具備了 __iter__⽅法的對象,就是⼀個可迭代對象。
>>> class MyList(object):
... def__init__(self):
... self.container = []
defadd(self, item):
... self.container.append(item)
def__iter__(self):
... """返回⼀個迭代器"""
... # 我們暫時忽略如何構造⼀個迭代器物件
... pass
>>> mylist = MyList()
>>> from collections import Iterable
>>> isinstance(mylist, Iterable)
True
>>>
# 這回測試發現添加了__iter__⽅法的mylist物件已經是⼀個可迭代對象了