17. Python 生成式 生成器 叠代器
1. 生成式和生成器
列表生成式是python受歡迎的一種語法之一,通過一句簡潔的語法,就能對元組元素進行過濾,還可以對得到的元素進行轉換處理。
語法格式:
[exp for val in collection if condition]
相當於
result = []
for val in collection:
if (condition):
result.append(exp)
例子:
a = [x*x for x in xrange(10) if x%2 == 0]
print (type(a))
print (a)
結果:
<type ‘list‘>
[0, 4, 16, 36, 64]
解釋:
① 由此取出xrange(10)從0到9
② 判斷 x*x 是偶數,就保留,存在新的字典中
③ 把所有符合x*x是偶數的元素都放到新的列表中返回。
通過列表生成式,我們可以創建一個列表,但是,受到內存限制,列表容量肯定是有限的;
如果創建一個包含100萬個元素的的列表,不僅占用很大的存儲空間,當我們僅僅需要訪問前面的幾個元素,後面絕大多數元素占的空間都浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素?
這樣一來就不必創建完整的list了,從而節省大量的空間。
在python中,這種一邊循環一邊計算的機制,稱為"生成器"(Generator)
生成器是一次生成一個值的特殊類型函數,可以將其視為可恢復函數,調用該函數將返回一個可用於生成連續 x 的值的生成器;
簡單的說就是在函數執行過程中,yield 語句會把你需要的的值返回給調用生成器的地方,然後退出函數,下次調用生成器函數
的時候,又從上次中斷的地方開始執行,而生成器內的所有變量參數會被保存下來供下一次使用。
要創建生成器有好幾種方法:
第一種方法
把一個列表生成式的[],改成(),這就創建了一個生成器。
例子:
lst = (x*x for x in xrange(1,101) if x%2 == 0)
print (lst)
print (type(lst))
print (lst.next())
print (lst.next())
print (lst.next())
print (lst.next())
print (lst.next())
print (lst.next())
結果:
<generator object <genexpr> at 0x02E72508>
<type ‘generator‘>
4
16
36
64
100
144
解釋:
generator 保存的是算法,每次調用next(),就計算出下一個元素的值,直到計算到最後一個元素為止。
第二種方法:
函數中定義列表生成器,即如果函數中包含yield關鍵字,那麽這個函數不再是一個普通函數,而是一個generator。
普通函數:
def func(n):
sum = 0
i = 0
while(i<n):
sum = sum + i
i += 1
print (sum)
func(10)
結果:
0
1
3
6
10
15
21
28
36
45
列表生成器:
def func(n):
sum = 0
i = 0
while(i<n):
sum = sum + i
i += 1
yield (sum)
for x in func(10):
print x
print (type(func(10)))
結果:
0
1
3
6
10
15
21
28
36
45
解釋:
① 以上函數有關鍵字 yield ,所以生成的是一個生成器;
② 通過for 循環調用生成器,當執行到yield的時候,返回sum值,sum為0,此時暫停並記錄sum的值;
③ 打印出sum的值,然後繼續往下去執行,跳入下一個循環 while(1<10)
④ 直到遇到yield的時候,返回sum的值
⑤ 反復執行3,4的步驟,直到循環結束,最終退出程序。
兩個函數的區別:
一個直接反回了表達式的結果列表,另一個是一個對象,該對象包含了對表達式結果的計算引用,通過循環可以直接輸出。
生成器不會一次性列出所有數據,當你用到的時候,再列出來,更加節約內存使用率。
普通函數和列表生成器的區別:
結果雖然相同,但是包含yield語句的函數會特地編譯成生成器,當函數被調用的時候,他們返回一個生成器對象,這個對象支持叠代器接口,
每當遇到yield關鍵字的時候,可以理解成函數的return語句,yield後面的值,就是返回值。但是不像一般函數在return後退出,生成器函數在生成
值後會自動掛起並暫停他們的執行和狀態,他的本地變量將保存狀態信息,這些信息在函數恢復時將再度有效,下次從yield下面的部分開始執行。
比如說上一次執行到3,下次開始時,找到3的位置,從6開始執行,(不會從頭開始執行),以此類推。
補充學習:http://www.jianshu.com/p/d09778f4e055
生成式:一次性生成所有數據,然後保存在內存中,適合小量的數據。
生成器:返回一個可叠代的對象,即"generator"對象,必須通過循環才可以一一列出所有結果。
2. 叠代器
iterable (可叠代對象) 和 iterator(叠代器)主要區別:
凡是可以用 for 循環的都是iterable(可叠代對象),可以通過循環調用出來的都是,比如:[],(),{},生成式....
凡是要通過 next()函數調用並獲得值的可叠代對象都是iterator(叠代器)
所以生成器可以被next()函數調用並不斷返回下一個值的對象稱為叠代器
可以簡單理解為 生成器 就是叠代器的可叠代對象。
凡是可作用於 for 循環的對象都是iterable 類
凡是可作用於 next()函數的對象都是iterator類型,他們表示一個惰性計算的序列。
作業:
九九乘法表
def func(n):
return ["{0}*{1}={2}".format(x,n,x*n) for x in xrange(1,n+1) ]
for i in xrange(1,10):
print " ".join(func(i))
本文出自 “筆記空間” 博客,請務必保留此出處http://286577399.blog.51cto.com/10467610/1978911
17. Python 生成式 生成器 叠代器