生成器(自身就是一個迭代器)
阿新 • • 發佈:2018-11-10
對於python中兩種延遲生成值的結構:
- 生成器函式
- 生成器表示式
我相信生成器函式各位都是不陌生的,就是在函式返回值前用yield,但是注意一點,這裡我並沒有說用yield代替return,兩個意義其實是不同的,所以不存在代替的問題,兩者可以共存。
例如:
def instance():
for i in range(1, 6):
yield i
if i == 4:
return "over"
所以兩者共存沒有牟盾。
當然利用關鍵字yield建立的函式是一個生成器,每次呼叫都會返回一個值。
同樣,生成器表示式也是一個節省記憶體空間的方法
其一般格式如下:
generator = (x for x in range(1, 8))
如上就是一個生成器表示式,重點強調的是,生成器函式和生成器表示式本身就是一個迭代器。
那麼為什麼說兩者可以節省記憶體空間呢?
如下的對比的例子
生成器函式:
def generator():
for i in range(1, 19):
yield i
每次呼叫是返回一個值,而不是將所有的值一次性返回,其呼叫可以在任何的迭代工具中,如:
for i in generator(): print(i) 或者: x = generator() # 產生一個生辰器函式例項 while True: print(next(x)) # 知道引發一個StopIteration錯誤
而相同效果的普通函式,如:
def ordinary():
return [i for in range(1, 19)]
會一次性在記憶體中生成這個列表,從而加重的記憶體的負擔,這種在比較大的結構中影響更加明顯。
對於我們的生成器表示式,它和列表解析有些相似之處。
生成器表示式:
generator = (x for x in range(1, 19))
同樣我們可以在任何的迭代工具中使用這個生成器(本身是迭代器)
相似結構的列表解析,如:
list = [x for x in range(1, 19)]
同樣,我們的列表解析生成了一個完整的列表,所以在資料較多時使用生成器表示式還是好的
重要的是,其實在資料較少時,使用列表解析更快,所以選哪個這裡考慮!