可叠代對象 詳解
阿新 • • 發佈:2018-11-21
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()函數了。
可叠代對象 詳解