概述
文章目录
- 1.定义
- 2.目的
- 3.如何创建生成器
- 4.生成器的使用
- 5.生成器的状态
- 6.向生成器发送消息
- 7.yield from
- 1.拼接可迭代对象
- 2.生成器的嵌套
1.定义
可以像迭代器那样用for循环来获取元素的函数
2.目的
实现延时计算,缓解大量内存下内存消耗过猛的问题
3.如何创建生成器
方法一:元祖推导式
#只有元祖推导式才是生成器
(i for i in range(5))
方法二:使用yield
- 当一个函数运行到 yield 后,函数的运行会暂停,并且会把 yield 后的值返回出去。
- 若 yield 没有接任何值,则返回 None
- yield 虽然返回了,但是函数并没有结束
4.生成器的使用
如何从生成器中取出元素,有如下三种方法
- for循环遍历
- next(gen)
- gen.send()
注意:
1.生成器在创建后并不会执行任何代码
2.gen.send(None)等价于next(gen)
5.生成器的状态
状态名 | 含义 |
---|---|
GEN_CREAED | 生成器创建,还未被激活 |
GEN_RUNNING | 解释器正在执行(只有在多线程应用中才能看到这个状态) |
GEN_SUSPENDED | 在yield表达式处暂停 |
GEN_CLOSED | 生成器执行结束 |
举例
from inspect import getgeneratorstate
gen = (x for x in range(3))
print(getgeneratorstate(gen)) # GEN_CREATED
print(next(gen)) # 0
getgeneratorstate(gen) # 'GEN_SUSPENDED'
next(gen) # 1
next(gen) # StopIteration
6.向生成器发送消息
def jumping_range(N):
index = 0
while index < N:
# 通过send()发送的信息将赋值给jump
jump = yield index
if jump is None:
jump = 1
index += jump
if __name__ == '__main__':
itr = jumping_range(5)
print(next(itr))
print(itr.send(2))
print(next(itr))
print(itr.send(-1))
注意:
1.jump= yield index,分成两部分:
yield index
是将indexreturn
给外部调用程序。
jump = yield
可以接收外部程序通过send()发送的信息,并赋值给jump
7.yield from
1.拼接可迭代对象
使用yield
# 字符串
astr='ABC'
# 列表
alist=[1,2,3]
# 字典
adict={"name":"wangbm","age":18}
# 生成器
agen=(i for i in range(4,8))
def gen(*args, **kw):
for item in args:
for i in item:
yield i
new_list=gen(astr, alist, adict, agen)
print(list(new_list))
# ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
使用yield from
# 字符串
astr='ABC'
# 列表
alist=[1,2,3]
# 字典
adict={"name":"wangbm","age":18}
# 生成器
agen=(i for i in range(4,8))
def gen(*args, **kw):
for item in args:
yield from item
new_list=gen(astr, alist, adict, agen)
print(list(new_list))
# ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
2.生成器的嵌套
1.使用委托生成器
# 子生成器
def average_gen():
total = 0
count = 0
average = 0
while True:
new_num = yield average
if new_num is None:
break
count += 1
total += new_num
average = total/count
# 每一次return,都意味着当前协程结束。
return total,count,average
# 委托生成器
def proxy_gen():
while True:
# 只有子生成器要结束(return)了,yield from左边的变量才会被赋值,后面的代码才会执行。
total, count, average = yield from average_gen()
print("计算完毕!!n总共传入 {} 个数值, 总和:{},平均数:{}".format(count, total, average))
# 调用方
def main():
calc_average = proxy_gen()
next(calc_average) # 预激协程
print(calc_average.send(10)) # 打印:10.0
print(calc_average.send(20)) # 打印:15.0
print(calc_average.send(30)) # 打印:20.0
calc_average.send(None) # 结束协程
# 如果此处再调用calc_average.send(10),由于上一协程已经结束,将重开一协程
if __name__ == '__main__':
main()
2.不使用委托生成器
# 子生成器
# 子生成器
def average_gen():
total = 0
count = 0
average = 0
while True:
new_num = yield average
if new_num is None:
break
count += 1
total += new_num
average = total/count
return total,count,average
# 调用方
def main():
calc_average = average_gen()
next(calc_average) # 预激协程
print(calc_average.send(10)) # 打印:10.0
print(calc_average.send(20)) # 打印:15.0
print(calc_average.send(30)) # 打印:20.0
# ----------------注意-----------------
try:
calc_average.send(None)
except StopIteration as e:
total, count, average = e.value
print("计算完毕!!n总共传入 {} 个数值, 总和:{},平均数:{}".format(count, total, average))
# ----------------注意-----------------
if __name__ == '__main__':
main()
最后
以上就是朴实世界为你收集整理的python生成器的全部内容,希望文章能够帮你解决python生成器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复