Python產生器和迭代器,Python產生器代器
1、產生器
通過列表產生式,我們可以直接建立一個列表。但是,受到記憶體的限制,列表容量肯定是有限的。而且,建立一個包含100萬個元素的列表,不僅佔有很大的儲存空間,如果我們僅僅訪問前面幾個元素,那後面絕大元素佔用的空間都白白浪費。所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素?這樣就不必須建立完整的list,從而節省大量的空間。在Python中,這樣一邊迴圈一邊計算的機制,稱為產生器:generator。
要建立一個generator有很多種方法。第一個方法很簡單,只要把一個列表的[]改為(),就建立了一個generator:
>>> L = [x*x for x in range(10)]>>> L[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x*x for x in range(10))>>> g<generator object <genexpr> at 0x7fafe19d2410>
如果要一個一個列印出產生器的元素,可以通過next()函數獲得:
>>> next(g)0>>> next(g)1>>> next(g)4>>> next(g)9>>> next(g)16>>> next(g)25>>> next(g)36>>> next(g)49>>> next(g)64>>> next(g)81>>> next(g)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration
每次調用next(),就計算出g的下一個元素,知道計算到最後一個元素,沒有更多元素,就會報錯。
#!/usr/bin/env pythong = (x*x for x in range(10))for n in g: print(n)====================================0149162536496481
所以通常都是用for迴圈來迭代它。
裴波拉切數列用列表產生式寫不出來,但是用函數可以:上面的函數和generato僅一步之遙
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'
注意指派陳述式:
a, b = b, a + b
相當於:
t = (b, a + b) # t是一個tuplea = t[0]b = t[1]
上面的函數和generato僅一步之遙,只需要把print(b)改為yield b就可以了
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done'
2、迭代器
可以直接作用於for迴圈的對象統稱為可迭代對象:Iterable。
可以使用Isinstance()判斷一個對象是否為Iterable對象。
>>> from collections import Iterable>>> isinstance([],Iterable)True>>> isinstance({},Iterable)True>>> isinstance('abc',Iterable)True>>> isinstance(100,Iterable)False>>>
可以被next()函數調用並返回下一個值得對象稱為迭代器:Iterator。
可以使用isinstance()判斷一個對象是否是Iterator對象:
>>> from collections import Iterator>>> isinstance((x for x in range(10)),Iterator)True>>> isinstance([],Iterator)False>>> isinstance({},Iterator)False