生成器表達式VS列表解析
列表解析都是在方括號裏面,而生成器表達式在元括號裏面,你只要碰到形式,這一步會給你返回一個結果集
生成器表達式不執行for語句,只有當調用next方法的時候纔會執行一次。
他們兩個的具體問題可以參考列表解析和生成器之間空間和時間的對比通過作爲返回值形式,體現出不同的處理方式
>>> [x**2 for x in range(4)] #列表解析生成了一個列表
[0, 1, 4, 9]
>>> (x**2 for x in range(4)) #生成器表達式,它生成一個生成器對象,只有通過調用next()來取值
<generator object <genexpr> at 0xb71465f4>
>>> G=(x**2 for x in range(4)) #生成器表達式每次只求一個值
>>> next(G)
0
>>> next(G)
1
list可以對一個生成器表達式一次性求出結果,其實拓展一下就是可以針對迭代對象。
>>> list(x**2 for x in range(4)) #list相當與把一個生成器對象的值,循環求出來了。
[0, 1, 4, 9]
生成器函數VS生成器表達式
如果僅僅是for上面的迭代,我們一般都可以用一個生成器函數跟生成器表達式來實現。
其實我感覺生成器表達式就相當與生成器函數被賦予了值的情況,因爲只有當對一個函數參數賦予了值以後,它才能成爲一個對象,在這裏是成爲一個generator object,但是你發現其實生成器表達式同樣也是生成一個generator對象。也就是生成器表達式是生成器函數的一個特例。
>>> def timestwo(x): #等價於上面生成器表達式
... for c in range(x):
... yield c**2
...
>>> G=timestwo(4)
>>> list(G)
[0, 1, 4, 9]
生成器VS內置數據類型
一個生成器對象只能有一個迭代器,(該對象可以通過生成器表達式生成或者對生成器函數指定實參)
內置數據類型可以有多個迭代器
>>> G=(c*4 for c in 'spam') #創建一個generator object
>>> I1=iter(G) #其實我們可以對G直接調用next,但是這裏爲了比較使用了iter,在這裏它實際上是返回自身的一個對象,就是G
>>> next(I1)
'ssss'
>>> I2=iter(G)
>>> next(I2) #值是緊接着上一個iterator後面的字符
'pppp'
>>> string='spam'
>>> s1=iter(string) #創建一個string的迭代對象
>>> next(s1)
's'
>>> s2=iter(string)
>>> next(s2)
's'