迭代器(iterator)與生成器(generator)是 Python 中比較經常使用又很容易混淆的兩個概念,今天就把它們梳理一遍,並舉一些經常使用的例子。git
2迭代器github
for 語句與可迭代對象(iterable object):for循環就是基於迭代器協議提供了一個統一的能夠遍歷全部對象的方法,即在遍歷以前,先調用對象的__iter__方法將其轉換成一個迭代器,而後使用迭代器協議去實現循環訪問,這樣全部的對象就均可以經過for循環來遍歷了,函數
for i in [123]:bthis
print(i)spa
輸出:1code
2orm
3對象
obj={'a':123,'b':456}ip
for i in obj:內存
print(i)
輸出:a
b
這些能夠用在 for
語句進行循環的對象就是可迭代對象。除了內置的數據類型(列表、元組、字符串、字典等)能夠經過 for
語句進行迭代,咱們也能夠本身建立一個容器,包含一系列元素,能夠經過 for
語句依次循環取出每個元素,這種容器就是迭代器(iterator)。除了用 for
遍歷,迭代器還能夠經過 next()
方法逐一讀取下一個元素。要建立一個迭代器有3種方法,其中前兩種分別是:
1爲容器對象添加 __iter__()
和 __next__()
方法(Python 2.7 中是 next()
);__iter__()
返回迭代器對象自己 self
,__next__()
則返回每次調用 next()
或迭代時的元素;
iter()
將可迭代對象轉化爲迭代器range
函數時,建議當長度太大時用 xrange
更快,在 Python 3.5 中已經去除了 xrange
只有一個相似迭代器同樣的 range
)。
yield
語句快速生成迭代器,省略了複雜的 __iter__()
& __next__()
方式:
def container(start, end):
while start < end:
yield start
start += 1
c = container(0, 5)
print(type(c))
print(next(c))
next(c)
for i in c:
print(i)
|
1
2
3
4
5
|
<class 'generator'>
0
2
3
4
|
簡單來講,yield
語句可讓普通函數變成一個生成器,而且相應的 __next__()
方法返回的是 yield
後面的值。一種更直觀的解釋是:程序執行到 yield
會返回值並暫停,再次調用 next()
時會從上次暫停的地方繼續開始執行:
def gen():
yield 5
yield "Hello"
yield "World"
yield 4
for i in gen():
print(i)
5HelloWorld4