6 生成器 yield 协程
1.生成器
----> 1 b = [x*2 for x in range(100000000000)] MemoryError:
想生成一个存放很多数据的列表,但是又不想内存占用太多
每次用一个生成一个,最好
2)列表生成器:生成多个值,每次生成1个
In [29]: c = (x*2 for x in range(10)) In [30]: c
Out[30]: <generator object <genexpr> at 0x7f8b5c0c6960> In [31]: next(c)
Out[31]: 0 In [32]: next(c)
Out[32]: 2 In [40]: next(c)
Out[40]: 18 In [41]: next(c) #迭代器没有数据就出现异常了
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-41-73b012f9653f> in <module>()
----> 1 next(c)
2.斐波那契数列
1)版本1:a,b = b,a+b
def creat_num():
a,b = 0,1 for i in range(5):
print(b)
a,b = b,a+b creat_num() 1
1
2
3
5
2)版本2:生成器 yield b
def creat_num():
a,b = 0,1 for i in range(5):
yield b
a,b = b,a+b creat_num()
3)版本3:当成模块导入
可以通过 next() 函数获得生成器的下一个返回值:
def creat_num():
print("--start---")
a,b = 0,1 for i in range(5):
print("--1--")
yield b #每次next执行到yield这里停止
print("--2---")
a,b = b,a+b
print("--3--")
print("--end---")
In [4]: a = creat_num() In [5]: a
Out[5]: <generator object creat_num at 0x7facd60b5a98> In [6]: next(a)
--start---
--1--
Out[6]: 1 In [7]: next(a)
--2---
--3--
--1--
Out[7]: 1 In [8]: next(a)
--2---
--3--
--1--
Out[8]: 2
4)版本4:next(a) 和 a.__next__()
def creat_num():
print("--start---")
a,b = 0,1 for i in range(5):
print("--1--")
yield b
print("--2---")
a,b = b,a+b
print("--3--")
print("--end---") #创建了1个生成器对象
a = creat_num() ret = next(a) #让a这个生成器对象开始执行,如果第一次执行,就从create_num开始部分执行
#如果是之前已经执行过了,就从上一次停止的位置开始执行
ret = next(a)
ret = next(a)
def creat_num():
print("--start---")
a,b = 0,1 for i in range(5):
print("--1--")
yield b
print("--2---")
a,b = b,a+b
print("--3--")
print("--end---") #创建了1个生成器对象
a = creat_num() ret = a.__next__()
print(ret) #注意:
#next(a)
#a.__next__()
#以上两种方式是一样的
5)版本5:循环取出生成器的值
def creat_num():
print("--start---")
a,b = 0,1 for i in range(5):
print("--1--")
yield b
print("--2---")
a,b = b,a+b
print("--3--")
print("--end---") #创建了1个生成器对象
a = creat_num() for i in a: #循环取出值
print(i)
--start---
--1--
1
--2---
--3--
--1--
1
--2---
--3--
--1--
2
--2---
--3--
--1--
3
--2---
--3--
--1--
5
--2---
--3--
--end---
3。send(‘haha’)
例子:执行到yield时,gen函数作用暂时保存,返回i的值;temp接收下次c.send("python"),send发送过来的值,c.next()等价c.send(None)
In [10]: def test():
....: i = 0
....: while i < 5:
....: temp = yield i
....: print(temp)
....: print(i)
....: i += 1
In [20]: t =test() In [21]: t.__next__()
Out[21]: 0 #yield i 的返回值 相当于return i In [22]: t.__next__()
--1 None
--2 0
Out[22]: 1 In [23]: t.__next__()
--1 None
--2 1
Out[23]: 2 In [24]: t.__next__()
--1 None
--2 2
Out[24]: 3 In [25]: t.send('haha') #相当于yield i = haha ,temp =haha
--1 haha
--2 3
Out[25]: 4 #到yield 停止 yield i 返回return i
2)第一次send(None)
In [26]: t = test() In [27]: t.send('lala')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-27-e48ba033e48c> in <module>()
----> 1 t.send('lala') TypeError: can't send non-None value to a just-started generator
#直接send 出现异常
In [29]: t.send(None) #第一次相当于t.__next__()
Out[29]: 0 In [30]: t.send('--lala')
--1 --lala
--2 0
Out[30]: 1
4.yield 多任务 协程
def test1():
while True:
print('===1')
yield None def test2():
while True:
print('---2')
yield None t1 =test1()
t2 = test2()
while True :
t1.__next__()
t2.__next__()
### 运行结果
===1
---2
===1
---2
===1
---2
===1
---2
===1
---2
===1
---2
5.总结
生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
生成器的特点:
- 节约内存
- 迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
6 生成器 yield 协程的更多相关文章
- python入门20180717-迭代器、生成器和协程
迭代器.生成器和协程 python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者支持下标索引的_getitem_方法,那么它就是一个可迭代对象. 可迭代的对象不一定就是迭代器 ...
- python基础----迭代器、生成器、协程函数及应用(面向过程实例)
一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代 ...
- Unity 3D中不得不说的yield协程与消息传递
1. 协程 在Unity 3D中,我们刚开始写脚本的时候肯定会遇到类似下面这样的需求:每隔3秒发射一个烟花.怪物死亡后20秒再复活之类的.刚开始的时候喜欢把这些东西都塞到Update里面去,就像下面这 ...
- [译]PEP 342--增强型生成器:协程
PEP原文 : https://www.python.org/dev/peps/pep-0342/ PEP标题: Coroutines via Enhanced Generators PEP作者: G ...
- Python复习笔记(八)迭代器和生成器和协程
1. 迭代器 1.1 可迭代对象 判断xxx_obj是否可以迭代 在第1步成立的前提下,调用 iter 函数得到 xxx_obj 对象的 __iter__ 方法的返回值 __iter__ 方法的返回值 ...
- Python学习——多线程,异步IO,生成器,协程
Python的语法是简洁的,也是难理解的. 比如yield关键字: def fun(): for i in range(5): print('test') x = yield i print('goo ...
- python 生成器与协程
生成器在迭代中以某种方式生成下一个值并且返回和next()调用一样的东西. 挂起返回出中间值并多次继续的协同程序被称作生成器. 语法上讲,生成器是一个带yield语句的函数.一个函数或者子程序只返回一 ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
- yield协程
1.Generator Generator , 一种可以返回迭代器的生成器,当程序运行到yield的时候,当前程序就唤起协程记录上下文,然后主函数继续操作,当需要操作的时候,在通过迭代器的next重新 ...
随机推荐
- 理解JavaScript中的去抖函数
何为去抖函数?在学习JavaScript去抖函数之前我们需要先弄明白这个概念.很多人都会把去抖跟节流两个概念弄混,但是这两个概念其实是很好理解的. 去抖函数(Debounce Function),是一 ...
- bzoj2816 [ZJOI2012]网络
Description http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf 正解:$link-cut \ tree$. $LCT$板子题,直接维护 ...
- Redis配置文件(3)常见的配置修改
常见的配置: redis.conf 配置项说明如下: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以 ...
- centos7 yum安装mysql后启动不起来问题
[root@localhost ~]# systemctl start mysqld 启动失败 Job for mysqld.service failed because the cont ...
- 配置文件和mybatis文件存放位置导致系统启动不了
1.web.xml <!-- 加载spring容器 --> <context-param> <param-name>contextConfigLocation< ...
- ajax简单做html查询删除(鲜花)
下载视频+项目链接:https://pan.baidu.com/s/1jUld3-Nqm3fUAzFSX8kjlQ
- CToolBarCtrl工具栏设置总结(转)
(一)工具条控制的主要功能 所谓工具条就是具有位图和分隔符组成的一组命令按钮,位图按钮部分可以是下推按钮.检查盒按钮.无线按 钮等.工具条对象类派生于主窗口架框类CframeWnd或CMDIFrame ...
- Network Security Threats
Network Security Combination of low-cost powerful computing and high-performance networks is a two-e ...
- 设置UI控件的Layer属性(边框可见,边框颜色,边框宽度,边框圆角)
设置UI控件的Layer属性 #import "ViewController.h" @interface ViewController () @property (strong, ...
- ASP.NET 跨域请求之jQuery的ajax jsonp的使用解惑 (转载)
前天在项目中写的一个ajax jsonp的使用,出现了问题:可以成功获得请求结果,但没有执行success方法,直接执行了error方法提示错误——ajax jsonp之前并没有用过,对其的理解为跟普 ...