1. 程式人生 > >Python之生成器(generator)和叠代器(Iterator)

Python之生成器(generator)和叠代器(Iterator)

聲明 創建 一個數 ID 少包 int yield 列表解析 next()

generator


生成器generator:一邊循環一邊計算的機制。

生成器是一個特殊的程序,可以被用於控制循環的叠代行為。python中的生成器是叠代器的一種,使用yield返回值函數,每次調用yield會暫停,可以使用next()函數和send()函數恢復生成器。

生成器類似於返回值為數組的一個函數,這個函數可以接受參數,可以被調用。但是,不同於一般函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這個消耗的內存數量將大大減小。因此,生成器看起來像是一個函數,但是表現得像叠代器。

創建generator

方法一:生成器表達式

生成器表達式:返回一個對象,這個對象只有在需要的時候才產生結果。

只要把一個列表生成式中的[]改為(),就創建一個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)