一、迭代器(Iterator)app
字符串,列表或元組對象均可用於建立迭代器:函數
實例1:spa
basket = ['apple', 'orange', 'pear', 'banana'] it = iter(basket) # 建立迭代器對象 # 輸出迭代器的下一個元素 print(next(it)) # 輸出迭代器的下一個元素 print(next(it))
以上代碼,輸出:code
apple orange
實例2:對象
basket = 'abc' it = iter(basket) # 建立迭代器對象 print(next(it)) # 輸出迭代器的下一個元素 print(next(it)) # 輸出迭代器的下一個元素
以上代碼,輸出:blog
a b
一般會和for語句搭配使用,如:內存
basket = 'abc' it = iter(basket) # 建立迭代器對象 for n in it: print(n)
以上代碼,輸出:ci
a b c
Python中 list,truple,str,dict這些均可以被迭代,但他們並非迭代器。爲何?字符串
由於和迭代器相比有一個很大的不一樣,list/truple/map/dict這些數據的大小是肯定的,也就是說有多少是可知的。但迭代器不是,迭代器不知道要執行多少次,因此能夠理解爲不知道有多少個元素,每調用一次next(),就會往下走一步,是惰性的。generator
判斷是否是能夠迭代,用Iterable
from collections import Iterable print('{} 是Iterable?', isinstance({}, Iterable)) print('() 是Iterable?', isinstance((), Iterable)) print('100 是Iterable?', isinstance(100, Iterable))
以上代碼,輸出:
{} 是Iterable? True () 是Iterable? True 100 是Iterable? False
判斷是否是迭代器,用Iterator
from collections import Iterator print('{} 是Iterable?', isinstance({}, Iterator)) print('() 是Iterable?', isinstance((), Iterator)) print('(x for x in range(10)) 是Iterable?', isinstance((x for x in range(10)), Iterator))
以上代碼,輸出:
{} 是Iterable? False () 是Iterable? False (x for x in range(10)) 是Iterable? True
凡是能夠for循環的,都是Iterable
凡是能夠next()的,都是Iterator
集合數據類型如list,truple,dict,str,都是Itrable不是Iterator,但能夠經過iter()函數得到一個Iterator對象
Python中的for循環就是經過next實現的
for x in [1, 2, 3, 4, 5]: pass
等價於
# 先獲取iterator對象 it = iter([1, 2, 3, 4, 5]) while True: try: # 獲取下一個值 x = next(it) except StopIteration: # 遇到StopIteration就退出循環 break
二、生成器
在 Python 中,使用了 yield 的函數被稱爲生成器(generator)。
def fibonacci(n): # 生成器函數 - 斐波那契 a, b, counter = 0, 1, 0 while True: if counter > n: return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f 是一個迭代器,由生成器返回生成
什麼狀況下須要使用 yield?一個函數 f,f 返回一個 list,這個 list 是動態計算出來的(無論是數學上的計算仍是邏輯上的讀取格式化),而且這個 list 會很大(不管是固定很大仍是隨着輸入參數的增大而增大),這個時候,咱們但願每次調用這個函數並使用迭代器進行循環的時候一個一個的獲得每一個 list 元素而不是直接獲得一個完整的 list 來節省內存,這個時候 yield 就頗有用。