1. 程式人生 > >可叠代對象 詳解

可叠代對象 詳解

pan 幫助 line 再次 作用 size 發現 self values

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()函數了。

可叠代對象 詳解