## 一场由yield引发的连串拷问

```>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x0062B568>```

```>>> next(g)
0
>>> next(g)
1```

``` 1 def foo(num):
2     print("foo starting")
3     while num < 5:
4         res = yield num
5         num = num + 1
6         print('res ::',res)
7
8 print("Starting First")
9 g = foo(0)
10
11 print("Starting for")
12 for n in g:
13     print('n ::',n)```

``` 1 Starting First
2 Starting for
3 foo starting
4 n :: 0
5 res :: None
6 n :: 1
7 res :: None
8 n :: 2
9 res :: None
10 n :: 3
11 res :: None
12 n :: 4
13 res :: None```

``` 1 listx = [1,2,3,4,5]
2
3 # 循环方法一
4 for n in listx:
5     print(n)
6
7 # 等价方法二
8 glistx = iter(listx)   # 转换为Iterator对象
9
10 while True:
11     try:
12         # 获得下一个值:
13         x = next(glistx)
14         print(x)
15     except StopIteration:
16         # 遇到StopIteration就退出循环
17         break```

``` 1 def foo(num):
2     print("foo starting")
3     while num < 5:
4         res = yield num
5         num = num + 1
6         print('res ::',res)
7
8 print("Starting First")
9 g = foo(0)
10
11 print("Starting for")
12 for n in g:
13     g.send(n + 100)
14     print('n ::',n)```

``` 1 Starting First
2 Starting for
3 foo starting
4 res :: 100
5 n :: 0
6 res :: None
7 res :: 102
8 n :: 2
9 res :: None
10 res :: 104
11 Traceback (most recent call last):
12   File "d:/VSCode/Python/genaratex.py", line 13, in <module>
13     g.send(n + 100)
14 StopIteration```

1. 生成器generator可以用()来定义，也可以使用iter()来转换，带yield的函数默认都是generator
2. next()取值时，除首次外都是从上次yield的地方开始执行的
3. Python中for循环的本质也是调用next()来逐个取值
4. send函数是先在yield处进行赋值，再进行next()操作，如果没有进行yield，直接调用send会报错找不到需要赋值的对象。