Python之生成器(generator)和叠代器(Iterator)
阿新 • • 發佈:2018-06-29
聲明 創建 一個數 ID 少包 int yield 列表解析 next()
只要把一個列表生成式中的[]改為(),就創建一個generator。
generator
生成器generator:一邊循環一邊計算的機制。
生成器是一個特殊的程序,可以被用於控制循環的叠代行為。python中的生成器是叠代器的一種,使用yield返回值函數,每次調用yield會暫停,可以使用next()函數和send()函數恢復生成器。
生成器類似於返回值為數組的一個函數,這個函數可以接受參數,可以被調用。但是,不同於一般函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這個消耗的內存數量將大大減小。因此,生成器看起來像是一個函數,但是表現得像叠代器。
創建generator
方法一:生成器表達式
生成器表達式:返回一個對象,這個對象只有在需要的時候才產生結果。
>>> list(x*x for x in range(5)) [0, 1, 4, 9, 16] >>> list[x*x for x in range(5)] File "<stdin>", line 1 list[x*x for x in range(5)] ^ SyntaxError: invalid syntax >>> #列表解析生成列表 ... [ x**3 for x in range(5)] [0, 1, 8, 27, 64] >>> #生成器表達式 ... ( x**3 for x in range(5)) <generator object <genexpr> at 0x105d8ba50> >>> list( x**3 for x in range(5)) [0, 1, 8, 27, 64]
方法二:生成器函數
也是用def定義,如果一個函數至少包含一個yield聲明(當然它也可以包含其他yield或return),那麽它就是一個generator.
yield和return都會讓函數返回一些東西,區別在於,return聲明徹底結束一個函數,而yield聲明是暫停函數,保存它的所有狀態,並且後續被調用後會繼續執行。
>> def my_gen(): ... n=1 ... print "first" ... yield n ... n+=1 ... print "second" ... yield n ... >>> for item in my_gen(): ... print item ... first 1 second 2 >>
一個叠代可以被寫成生成器函數,也可以被寫成生成器表達式,均支持自動和手動叠代。而且這些生成器只支持一個active叠代,也就是生成器的叠代器就是生成器本身。
叠代器(叠代就是循環)
可以直接作用於for循環的數據類型:
- 集合數據類型,如list、tuple、dict、set、str
- generator,包括生成器函數和表達式?
- 這些可以直接作用於for循環對象的統稱為可叠代對象:Iterable
- 可以被next()函數調用並不斷返回下一個值的對象成為叠代器:Iterator
- 生成器都是Iterator對象,但list、dict、str雖然是Iterable(可叠代對象),卻不是Iterator(叠代器)。
- 把list、dict、str等Iterable變成Iterator可以使用iter()函數。
Iterator對象表示的是一個數據流,Iterator對象可以被next()函數調用並不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它才會計算。
小結
- 凡是可作用於for循環的對象都是Iterable類型;
- 凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
- 集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。
Python之生成器(generator)和叠代器(Iterator)