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è¯å�¥ä¼šè‡ªåЍ处ç�†è¿™äº›ç»†èŠ‚ï¼Œæ‰€ä»¥ä½ æ— éœ€æ‹…å¿ƒã€‚