4.3 使用生成器創(chuàng)建新的迭代模式

2018-02-24 15:26 更新

問(wèn)題

你想實(shí)現(xiàn)一個(gè)自定義迭代模式,跟普通的內(nèi)置函數(shù)比如 range() , reversed() 不一樣。

解決方案

如果你想實(shí)現(xiàn)一種新的迭代模式,使用一個(gè)生成器函數(shù)來(lái)定義它。下面是一個(gè)生產(chǎn)某個(gè)范圍內(nèi)浮點(diǎn)數(shù)的生成器:

def frange(start, stop, increment):
    x = start
    while x < stop:
        yield x
        x += increment

為了使用這個(gè)函數(shù),你可以用for循環(huán)迭代它或者使用其他接受一個(gè)可迭代對(duì)象的函數(shù)(比如 sum() , list() 等)。示例如下:

>>> for n in frange(0, 4, 0.5):
...     print(n)
...
0
0.5
1.0
1.5
2.0
2.5
3.0
3.5
>>> list(frange(0, 1, 0.125))
[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]
>>>

討論

一個(gè)函數(shù)中需要有一個(gè)yield語(yǔ)句即可將其轉(zhuǎn)換為一個(gè)生成器。跟普通函數(shù)不同的是,生成器只能用于迭代操作。下面是一個(gè)實(shí)驗(yàn),向你展示這樣的函數(shù)底層工作機(jī)制:

>>> def countdown(n):
...     print('Starting to count from', n)
...     while n > 0:
...         yield n
...         n -= 1
...     print('Done!')
...

>>> # Create the generator, notice no output appears
>>> c = countdown(3)
>>> c
<generator object countdown at 0x1006a0af0>

>>> # Run to first yield and emit a value
>>> next(c)
Starting to count from 3
3

>>> # Run to the next yield
>>> next(c)
2

>>> # Run to next yield
>>> next(c)
1

>>> # Run to next yield (iteration stops)
>>> next(c)
Done!
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
StopIteration
>>>

一個(gè)生成器函數(shù)主要特征是它只會(huì)回應(yīng)在迭代中使用到的”next”操作。一旦生成器函數(shù)返回退出,迭代終止。我們?cè)诘型ǔJ褂玫膄or語(yǔ)句會(huì)自動(dòng)處理這些細(xì)節(jié),所以你無(wú)需擔(dān)心。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)