# 什么是生成器

```In [1]: l = [ x*2 for x in range(5) ]

In [2]: l
Out[2]: [0, 2, 4, 6, 8]```

# 将列表生成式的[]改成()

```In [3]: l = ( x*2 for x in range(5) )

In [4]: l
Out[4]: <generator object <genexpr> at 0x103ca38b8> # 生成器```

```In [5]: next(l)
Out[5]: 0

In [6]: next(l)
Out[6]: 2

In [7]: l.__next__()
Out[7]: 4```

next() 与 生成器的 next() 方法作用相同

```In [9]: next(l)
Out[9]: 6

In [10]: next(l)
Out[10]: 8

In [11]: next(l)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-11-cdc8a39da60d> in <module>()
----> 1 next(l)

StopIteration:```

```In [15]: l = ( x*2 for x in range(5) )

In [16]: for x in l:
...:     print(x)
...:
0
2
4
6
8```

# 用 yield 创建生成器

```In [18]: def fib(times):
...:     n = 0
...:     a, b = 0, 1
...:     while n < times:
...:         print(b)
...:         a, b = b, a+b
...:         n += 1
...:     return 'done'
...:
...:

In [19]: fib(5)
1
1
2
3
5
Out[19]: 'done'

In [20]: def fib(times):
...:     n = 0
...:     a, b = 0, 1
...:     while n < times:
...:         yield(b) # 将print改为yield, 函数就成为了生成器
...:         a, b = b, a+b
...:         n += 1
...:     return 'done'
...:
...:

In [21]: F = fib(5)

In [22]: next(F)
Out[22]: 1

In [23]: next(F)
Out[23]: 1

In [24]: next(F)
Out[24]: 2

In [25]: next(F)
Out[25]: 3

In [26]: next(F)
Out[26]: 5

In [27]: next(F)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-27-372178f5f53b> in <module>()
----> 1 next(F)

StopIteration: done

In [28]: F
Out[28]: <generator object fib at 0x103ca3570> # 生成器```

```In [7]: for x in fib(5):
...:     print(x)
...:
1
1
2
3
5```

for循环调用能将结果输出，可是并没有捕获到fib()的return值。返回值其实是包含在StopIteration的value中，因此必须捕获StopIteration异常

```In [8]: F = fib(5)

In [9]: while True:
...:     try:
...:         x = next(F)
...:         print(x)
...:     except StopIteration as e:
...:         print('返回值是:%s' %e.value)
...:         break
...:
1
1
2
3
5

# yield的执行流程

```In [20]: def fib(times):
...:     n = 0
...:     a, b = 0, 1
...:     while n < times:
...:         print('%s_before_yield' %n)
...:         yield(b) # 将print改为yield, 函数就成为了生成器
...:         print('%s_after_yield' %n)
...:         a, b = b, a+b
...:         n += 1
...:     return 'done'
...:
...:

In [21]: F = fib(5)

In [22]: next(F)
0_before_yield
Out[22]: 1 # 执行到yield, 程序停住，不再往下执行，并记住当前的执行位置

In [23]: next(F)
0_after_yield
1_before_yield
Out[23]: 1 # 从上一处的停顿往下继续执行，同样到yield处继续停住

In [24]: next(F)
1_after_yield
2_before_yield
Out[24]: 2

In [25]: next(F)
2_after_yield
3_before_yield
Out[25]: 3

In [26]: next(F)
3_after_yield
4_before_yield
Out[26]: 5

In [27]: next(F) # 超出生成器的范围报错
4_after_yield
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-27-372178f5f53b> in <module>()
----> 1 next(F)

StopIteration: done```

python

0 条评论

## 相关文章

1363

1174

### leetcode-179-Largest Number（理解规则，自定义cmp函数进行排序）

1、这道题给定一个vector，里面存放着int类型的非负整数，要求把这些非负整数拼起来，尽可能拼成一个最大的整数。

1913

5774

901

1322

### JS入门难点解析10-创建对象

（注1：如果有问题欢迎留言探讨，一起学习！转载请注明出处，喜欢可以点个赞哦！） （注2：更多内容请查看我的目录。）

1243

### 1798: [Ahoi2009]Seq 维护序列seq

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 2930...

3065

3419

### JS魔法堂：再识Number type

Brief　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　   本来只打算理解JS中0.1 + 0.2 == 0.300000000000000...

2295