Python生成器和迭代器

生成器generator

盡管列表解析可以方便地創建列表,但會占用內存,而且容量有限(受內存影響)。如果列表元素可以按照某種算法推算出來,那我們就可以創建生成器generator,這樣就不必創建完整的list。生成的generator可以理解為iterator,用for循環來迭代它。如果推算的算法比較復雜,用類似for循環無法實現,可以用定義函數來實現。根本上來說,迭代器就是一個有nest()方法的對象。條目全部取出后,會引發一個 StopIteration 異常。生成器表達式就好像是惰性的列表解析。

語法:

(expression for iter_val in iterator)
#語法與列表解析一樣,只需把`[]`改成`()`。

例如計算文本文件中非空字符總和,如果用列表解析,內存性能會很低,用生成器表達式會很方便實惠:

sum(len(word) for line in date for word in line.split())

另一種創建生成器的方法:定義一個函數,采用yield語句:

aa='def'
def bb():
    yield 'a'
    yield 'b'
    yield 'c'
    
aa_product_bb=[x+y for x in aa for y in bb()]
# return ['da','db','dc','ea','eb','ec','fa','fb','fc']

這里在列表解析中,兩個for循環,有一個是生成器bb(),另一個是可迭代對象。如果兩個都是迭代器,就會出問題!具體的原因未知...

利用yield語句定義fibonaci數列:

def fib(max):
    n,a,b=0,0,1
    while n<max:
        yiled b
        a,b=,b,a+b
        n+=1
    return 'done'

函數定義中包含yield關鍵字,這個函數就不是一個普通的函數,而是一個generator

迭代器

可以直接用for循環作用的數據類型有:

  • 集合數據類型:list,tuple,dict,set,str.
  • generator: 生成器及帶yield的generator function.
    這些可以直接用for循環作用的對象統稱為可迭代對象Iterable。可以用isinstance()判斷對象是否為Iterable對象:
isinstance((x for x in range(10)),Iterable) #return True

可以被next()函數調用并不斷返回下一個值的對象稱為迭代器:Iterator.
生成器都是Iterator對象,但list,dict,str雖然是Iterable,卻不是Iterator,可以利用函數iter()使它們變成Iterator.
Iterator可以表示一個無限大的數據流,且不會占用大內存。for循環本質上不斷調用next(0函數實現的。

[廖雪峰網站](http://www.liaoxuefeng.com

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容