4.3 使用生�器创建新的迭代模�¶

问题¶

你想实现一个自定义迭代模�,跟普通的内置函数比如 range() , reversed() �一样。

解决方案¶

如果你想实现一�新的迭代模�,使用一个生�器函数�定义它。 下�是一个生产�个范围内浮点数的生�器:

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

为了使用这个函数, 你�以用for循环迭代它或者使用其他接�一个�迭代对象的函数(比如 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]
>>>

讨论¶

一个函数中需�有一个 yield 语���将其转�为一个生�器。 跟普通函数��的是,生�器�能用于迭代�作。 下�是一个实验,�你展示这样的函数底层工作机制:

>>> 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
>>>

一个生�器函数主�特�是它�会回应在迭代中使用到的 next �作。 一旦生�器函数返回退出,迭代终止。我们在迭代中通常使用的for语�会自动处�这些细节,所以你无需担心。