1. 程式人生 > >可迭代物件 詳解

可迭代物件 詳解

可迭代物件詳解

1.可迭代物件 我們已經知道可以對list、tuple、dict、set、str等型別的資料使用for...in...的迴圈語法從其中依次拿到資料進行使用,我們把這樣的過程稱為遍歷,也叫迭代。 把可以通過for...in...這類語句迭代讀取一條資料供我們使用的物件稱之為可迭代物件(Iterable)。 在Python中,迭代可通過for ... in來完成,例如列表的迭代:
>>> for num in [11, 22 , 33]:
...         print(num)
...
11
22
33

 

list這種資料型別雖然有下標,但很多其他資料型別是沒有下標的,但是,只要是可迭代物件,無論有無下標,都可以迭代,比如dict就可以迭代:

>>> d = {'a': 11, 'b': 22, 'c': 33}
>>> for key in d:
... print(key)
...
a
c
b
因為dict的儲存不是按照list的方式順序排列,所以,迭代出的結果順序很可能不一樣。 預設情況下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同時迭代key和value,可以用for k, v in d.items()。

 

由於字串也是可迭代物件,因此,也可以作用於for迴圈:

>>> for str in 'python':
...         print(str)
...
p
y
t
h
o
n

 

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 = []
...   def add(self, item):
...     self.container.append(item)
...   def __iter__(self):
...     """返回一個迭代器"""
...     # 我們暫時忽略如何構造一個迭代器物件
...     pass
...
>>> mylist = MyList()
>>> from collections import Iterable
>>> isinstance(mylist, Iterable)
True
>>>
# 這回測試發現添加了__iter__方法的mylist物件已經是一個可迭代物件了

4. iter()函式與next()函式

list、tuple等都是可迭代物件,我們可以通過iter()函式獲取這些可迭代物件的迭代器。然後我們可以對獲取到的迭代器不斷使用next()函式來獲取下一條資料。iter()函式實際上就是呼叫了可迭代物件的__iter__方法。
>>> li = [11, 22, 33, 44, 55]
>>> li_iter = iter(li)
>>> next(li_iter)
11
>>> next(li_iter) 22
>>> next(li_iter) 33
>>> next(li_iter) 44
>>> next(li_iter) 55
>>> next(li_iter) Traceback (most recent call last):   File "<stdin>", line 1, in <module> StopIteration >>>

注意,當我們已經迭代完最後一個數據之後,再次呼叫next()函式會丟擲StopIteration的異常,來告訴我們所有資料都已迭代完成,不用再執行next()函數了。