生成器

python2.5之后出现的一个可迭代对象。生成器的底层实现使用迭代器实现。

1. 基本概念

  •  **生成器,给一个函数生成一个懒加载(按需加载)的迭代器**
    
  •  **生成器的特征:生成器不会一次性计算出存储的所有数据,而是根据需要,一次仅计算一个数据。**
    

2.生成器的实现

生成器的数据可以通过两种方式获得:
1. next /send
2. for循环遍历

(1)生成器表达式

     元组推导式==生成器
print([i**2 for i in range(1,100)])
x=(i**2 for i in range(1,100))
print(next(x))
for i in x:
    print(i)

(2)生成器函数

带有yield关键字的函数,就是生成器函数
yield:能够让程序暂定到yield的位置,产出值
普通函数

def f():
    print("函数的开始")
    for i in range(1,101):
        print(i)

生成器函数

def f():
print("函数的开始")
for i in range(1,101):
print("yield之前{}".format(i))
yield i
print("yield之后{}".format(i))
# print(i)

生成器函数调用的时候,不是直接执行,而是创建了一个生成器对象。


> 生成器函数和普通函数的区别:  	
> 1. 生成器函数会包含一个或者多个yield  
> 2. 被调用的时候,不是直接执行,而是返回一个生成器对象,底层迭代器  
> 3. 可以通过next方法获得内部的元素,也可以通过for遍历内部的元素  
> 4. 当函数终止时,再次获得元素,会报StopIteration的异常  
> 5. 函数一旦执行遇到yield,函数执行会被暂停,会将控制权交给调用者。  	

"""
# 3. yield表达式
- 第一次调用生成器:产生了生成器对象
- next:激活生成器
- send函数:是生成器对象下的方法,可以获得生成器的产出值
- 激活生成器 next(g)   g.send(None) 等价

```python
#需求:产生1 2 3 4 5 4 3 2 1 2 3 4......
# 使用生成器编程的思路:
# (1)抓住主线
# (2)在主线中插入生成器调用
# 编写一个生成器:有人告诉大了,还是小了


# def gen():
#     msg=""
#     while True:
#         x=yield msg
#         if x==5:
#             msg="too big ,小一点"
#         elif x==1:
#             msg="too small,大一点"
#
# # 产生一个生成器对象
#
# g=gen()
# g.send(None)
# x=1
# while True:
#     time.sleep(0.5)
#     print(x)
#     msg=g.send(x)
#     if msg=="too big ,小一点":
#         x-=1
#     else:
#         x+=1

#方式二
def gen():
    x=0
    while True:
        msg=  yield x
        if msg=="too big,小一点":
            x-=1
        else :
            x+=1

g=gen()
g.send(None)
msg=""
while True:
    x=g.send(msg)
    time.sleep(0.5)
    print(x)
    if x==5:
        msg="too big,小一点"
    elif x==1:
        msg="too small,大一点"
原文地址:https://www.cnblogs.com/geoffreyone/p/9892696.html