(十)python3 生成器
生成器(generator):在 Python 中,不必创建完整的 list,从而节省大量的空间。一边循环一边计算的机制。
创建一个 generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的 [] 改成 () ,就创建了一个 generator:
>>> 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 0x1022ef630>
如果要一个一个打印出来,可以通过 next() 函数获得 generator 的下一个返回值:
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
...
...
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):File "<stdin>", line 1, in <module> StopIteration
generator 保存的是算法,每次调用 next(g) ,就计算出 g 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration 的错误。
常用的方法是使用for 循环,因为 generator 也是可迭代对象:
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81
generator 非常强大。如果推算的算法比较复杂,用类似列表生成式的 for循环无法实现的时候,还可以用函数来实现。
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
>>> fib(6)
1
1
2
3
5
8
'done'
上面的函数和 generator 仅一步之遥。要把 fib 函数变成generator,只需要把 print(b) 改为 yield b 就可以了:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generator:
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>
函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成generator 的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。
for 循环调用 generator 时,发现拿不到 generator 的 return 语句的返回值。如果想要拿到返回值,必须捕获 StopIteration 错误,返回值包含在 StopIteration 的 value 中:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
小结
generator 是非常强大的工具,在 Python 中,可以简单地把列表生成式改成 generator,也可以通过函数实现复杂逻辑的 generator。
要理解 generator 的工作原理,它是在 for 循环的过程中不断计算出下一个元素,并在适当的条件结束 for 循环。对于函数改成的 generator 来说,遇到 return 语句或者执行到函数体最后一行语句,就是结束 generator的指令, for 循环随之结束。
(十)python3 生成器的更多相关文章
- 第十三天python3 生成器yield
生成器generator 生成器指的是生成器对象,可由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象: 生成器函数 函数体中包含yield语句的函数,返 ...
- python3 生成器&迭代器
#Author by Andy#_*_ coding:utf-8 _*_import timefrom collections import Iterable#列表生成式def func(): lis ...
- python3 生成器初识 NLP第五条
话不多说,先把第五条抄一遍: 五,沟通的意义在于对方的回应 沟通没有对与错,只有“有效果”或者“没有效果”之分. 自己说得多“对”没有意义,对方收到你想表达的讯息才是沟通的意义. 因此自己说什么不重要 ...
- python3 生成器和生成器表达式
''' 生成器:函数中有yield就是生成器函数 生成器本质是一个迭代器 yield后面的值会作为返回值返回. ''' def func(): print("apple") pri ...
- Python3 生成器
生成器(genetor): 1>生成器只有在调用的时候才会生成相应的数据: 2>生成器只记录当前位置,有一个__next__()方法 3>yield可以实现单线程先的并发运算 1.列 ...
- python3 生成器表达式
生成器表达式 [i for i in range(100)] #列表解析 与列表解析的不同是,列表解析用中括号,生成器表达式用小括号 g = (i for i in range(1000)) #生成器 ...
- python3 - 生成器genarator
在Python中,这种一边循环一边计算的机制,称为生成器:generator. 生成器保存的是算法,每次调用 next() ,就计算出 下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 ...
- python3 生成器笔记
#生成器def MyDemo(M): for i in range(M): yield i**2for item in MyDemo(9): print(item) # #生成器import sysa ...
- 净心诀---python3生成器进阶
列表推导式 把需要用一个函数写成的小功能,利用一行表达式完成 例子: l = [1,2,3,4,5] # 所有的偶数都放到新的列表中 # 正常函数 def Lst(): li = [] for i i ...
随机推荐
- js 调试方法两种
JS的错误捕获一般有下面两种方式: 1. 异常捕获常用方法是 try/catch/ throw /finally 2. 全局捕获window.onerror 1. try/catch/throw/fi ...
- 使用pabot并行执行robotframework用例
主要观点:使用pabot并行运行robotframework,可以解决:robotframework执行案例时间长的问题 解决执行案例时间长的方案: 目的: 缩短案例的运行时间 两种方法: 将大的项目 ...
- cenos mkdir 无法创建文件夹,即便文件权限为777
SELinux 拒绝了httpd的方式去读写此目录 chcon -R -t httpd_sys_content_rw_t /var/www/html
- jsp声明周期
https://www.w3cschool.cn/jsp/jsp-life-cycle.html 几点注意: jsp初始化期: 容器载入jsp文件后,它会在为请求提供任何服务前调用jspinit()方 ...
- [转]mysql日志详细解析
转自:http://pangge.blog.51cto.com/6013757/1319304 MySQL日志: 主要包含:错误日志.查询日志.慢查询日志.事务日志.二进制日志: 日志是mysql数据 ...
- Windows 7操作系统下PHP 7的安装与配置(图文详解)
前提博客 Windows 7操作系统下Apache的安装与配置(图文详解) 从官网下载 PHP的官网 http://www.php.net/ 特意,新建这么一个目录 ...
- Spring && 实验IOC
一.Spring作用 1.生态体系庞大,全能型选手![springmvc是其一个子模块,jdbcTemplate能直接操作数据库!] 2.将其他组件粘合在一起 3.IOC容器和AOP[As ...
- php(三)使用PDO链接数据库
1.启动 mysql数据库,打开图形化控制界面 2.新建一个数据库 3.创建一个数据表 4.给数据表添加数据 id是数字类型的 类型选择int长度 11 username 等其他数据 会是字符串形 ...
- Android拍照得到全尺寸图片并进行压缩/拍照或者图库选择 压缩后 图片 上传
http://www.jb51.net/article/77223.htm https://www.cnblogs.com/breeze1988/p/4019510.html
- Node.js——fs常用API
文件状态 文件删除 文件信息 读取文件夹 文件的截取 创建文件夹 删除目录 文件监视,可以设置监视频率 文件重命名,可以用来剪切文件 注意 fs.open() fs.close() 这是最原始的读写方 ...