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,大一点"