020.Python生成器和生成器函数
一 生成器
1.1 基本概念
元组推导式是是生成器(generator)
生成器定义
- 生成器可以实现自定义,迭代器是系统内置的,不能够更改
- 生成器的本质就是迭代器,只不过可以自定义.
生成器有两种定义的方式:
- 生成器表达式 (里面是推导式,外面用圆括号)
- 生成器函数
1.2 元组推导式的形式来写生成器
gen = (i * 2 for i in range(5))
print(gen)
from collections import Iterator
print(isinstance(gen,Iterator))
执行
[root@node10 python]# python3 test.py
<generator object <genexpr> at 0x7fb5ec2e6200>
True
1.3 使用for调用生成器
gen = (i * 2 for i in range(5))
print(gen)
from collections import Iterator
print(isinstance(gen,Iterator))
for i in gen:
print (i)
执行
[root@node10 python]# python3 test.py
<generator object <genexpr> at 0x7fd817c1f200>
True
0
2
4
6
8
1.4 用next进行调用生成器
gen = (i * 2 for i in range(5))
print(gen)
from collections import Iterator
print(isinstance(gen,Iterator))
for i in gen:
print (i)
gen = (i * 2 for i in range(5))
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
执行
[root@node10 python]# python3 test.py
<generator object <genexpr> at 0x7f0b564d0200>
True
0
2
4
6
8
0
2
4
6
8
越界错误
gen = (i * 2 for i in range(5))
print(gen)
from collections import Iterator
print(isinstance(gen,Iterator))
for i in gen:
print (i)
gen = (i * 2 for i in range(5))
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
#在添加一个会出现越界错误
res = next(gen)
print(res)
执行

1.5 利用for 和next 配合使用 调用生成器
gen = (i * 2 for i in range(5))
print(gen)
from collections import Iterator
print(isinstance(gen,Iterator))
gen = (i * 2 for i in range(5))
for i in range(3):
res = next(gen)
print(res)
执行
[root@node10 python]# python3 test.py
<generator object <genexpr> at 0x7f5e78ef1200>
True
0
2
4
二 生成器函数
2.1 yield 生成器函数
yield 类似于 return
共同点在于:执行到这句话都会把值返回出去
不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
而return直接终止函数,每次重头调用.
yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用
定义一个生成器
def func():
print("one")
yield 1 print("two")
yield 2 print("three")
yield 3 # 初始化生成器函数 => 返回一个生成器对象 简称生成器
gen = func() res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
执行
[root@node10 python]# python3 test.py
one
1
two
2
three
3
执行过程
首先初始化生成器函数 返回生成器对象,简称生成器
有了生成器之后 可以使用next进行依次的调用
第一次 print(one) 记录当前的状态,暂停等待下一次调用 通过yield 1 返回1 ,阻塞代码
第二次 print(two) 记录当前的状态,暂停等待下一次调用 通过yield 2 返回2 ,阻塞代码
第三次 print(three) 记录当前的状态,暂停等待下一次调用 通过yield 3 返回3 ,阻塞代码
到此已经没有值可以在拿出来了,如果在调用,直接越界报错.
优化生成器
def func():
for i in range(1,101):
yield "我的球衣号码是%d" % (i) # 初始化生成器函数 => 返回一个生成器对象
gen = func() for i in range(30):
res = next(gen)
print(res) for i in range(50):
res = next(gen)
print(res)
2.2 send生成器函数
把值发送给上一个yield 进行接收
next和send区别:
- next 只能取值
- send 不但能取值,还能发送值
send注意点:
- 第一个 send 不能给 yield 传值 默认只能写None (语法的硬性要求)
- 最后一个yield 接受不到send的发送值
def func():
print("start")
res = yield 1
print(res) res = yield 2
print(res) res = yield 3 print(res)
print("end")
#初始化生成器函数,生成生成器
gen = func()
# 生成器.send 第一次发送的时候必须参数是None 硬性语法
res = gen.send(None) #这里相当于res = next(gen)
print(res)
执行
[root@node10 python]# python3 test.py
start
1
第二次可以自定义要发送的值
def func():
print("start")
res = yield 1
print(res) res = yield 2
print(res) res = yield 3 print(res)
print("end")
gen = func()
# 生成器.send 第一次发送的时候必须参数是None 硬性语法
res = gen.send(None)
print(res)
res = gen.send("111")
print(res) res = gen.send("222")
print(res)
执行
[root@node10 python]# python3 test.py
start
1
111
2
222
3
如果没有yield了 , 就没有返回值给你, 在调用直接报错
如果就像在最后一次调用的时候执行剩下的没跑完的代码,使用try..except..来进行异常处理
def func():
print("start")
res = yield 1
print(res) res = yield 2
print(res) res = yield 3 print(res)
print("end")
gen = func()
# 生成器.send 第一次发送的时候必须参数是None 硬性语法
res = gen.send(None)
print(res)
res = gen.send("111")
print(res) res = gen.send("222")
print(res) res = gen.send("222")
print(res)
执行
[root@node10 python]# python3 test.py
start
1
111
2
222
3
222
end
Traceback (most recent call last):
File "test.py", line 25, in <module>
res = gen.send("222")
StopIteration

执行过程
发送的时候 是先发送 ,后接受 #第一次发送的时候必须参数是None 硬性语法
print(start) 记录当前状态, 把yield 1这个值返回取出 , 暂定阻塞,等待下一次调用.
# 第二次调用时,可以自定义要发送的值 被yield 1 这一行收走了,res接收到send发送过去的值为111
那么从这一行继续向下执行
print(res) 111
res = yield 2
把2 返回给res = gen.send(111) 这一行 res 接收到2 print(res) #第三次调用时,发送自定义值222,被res = yield 2接收到 print(res) => 222
然后执行res = yield 3 记录当前状态,把yield 3 这个值返回取出, 代码暂停阻塞,等待下一次调用.
2.3 yield from 函数
- 将一个可迭代对象变成一个迭代器返回
def func():
listvar = [1,2,3,4,4,5]
# yield listvar
yield from listvar # 初始化生成器函数 返回生成器对象 简称生成器
gen = func()
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
print("<=for=>")
for i in gen:
print(i)
执行
[root@node10 python]# python3 test.py
1
2
3
4
<=for=>
4
5
020.Python生成器和生成器函数的更多相关文章
- python迭代器和生成器(3元运算,列表生成式,生成器表达式,生成器函数)
1.1迭代器 什么是迭代器: 迭代器是一个可以记住遍历的位置对象 迭代器对象从集合的第一个元素元素开始访问,直到所有元素被访问完结束,迭代器只能往前不会后退. 迭代器有两个基本方法:iter ,nex ...
- python中的生成器函数是如何工作的?
以下内容基于python3.4 1. python中的普通函数是怎么运行的? 当一个python函数在执行时,它会在相应的python栈帧上运行,栈帧表示程序运行时函数调用栈中的某一帧.想要获得某个函 ...
- python学习 day11 (3月16日)----(生成器内置函数)
1生成器 1生成器的本质 一定是迭代器(反之不一定(用send(生成器特有方法)验证))2生成器是可以让程序员自己定义的一个迭代器3生成器的好处,节省内存空间4生成器的特性,一次性的,惰性机制,从上往 ...
- 【学习笔记】--- 老男孩学Python,day13 生成器,生成器函数,各种推倒式和生成器表达式
1. 生成器和生成器函数 生成器的本质就是迭代器 生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 2. 生成器函数: 函数中包含了yield的就是生成 ...
- Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数
Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: 就是迭代器 生成器产生的方式: 1.生成器函数
- Python入门篇-生成器函数
Python入门篇-生成器函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.生成器概述 1>.生成器generator 生成器指的是生成器对象,可以由生成器表达式得到, ...
- python之序列去重以及生成器、生成器函数、生成器表达式与迭代器浅谈
首先要明确序列值类型是否可哈希,因为可哈希的值很简单就可以用 in /not in 写个生成器去判断,如果是不可哈希的就要去转换为可哈希的再用 in/not in 去判断 原地不可变类型(可哈希): ...
- python之迭代器 生成器 枚举 常用内置函数 递归
迭代器 迭代器对象:有__next__()方法的对象是迭代器对象,迭代器对象依赖__next__()方法进行依次取值 with open('text.txt','rb',) as f: res = f ...
- Python第六章-函数05-迭代器&生成器
python作为一个既面向对象,又支持函数式编程的语言,函数的使用方面有很多特点. 比如:闭包,装饰器,迭代器等 函数的高级应用 容器:生活中常见的容器有哪些?袋子,盆子,水杯,书包,铅笔盒... 容 ...
随机推荐
- 2020-BUAA OO-面向对象设计与构造-HW11中对ageVar采用缓存优化的等价性证明(包括溢出情况)
HW11中对ageVar采用缓存优化的等价性证明(包括溢出情况) 概要 我们知道,第三次作业里age上限变为2000,而如果缓存年龄的平方和,2000*2000*800 > 2147483647 ...
- 解决CentOS虚拟机无法显示本地IP问题
1 问题描述 CentOS虚拟机无法显示本地ip,如图: 2 尝试过的方法 参考过此处的解决方法,把网卡配置中的ONBOOT修改为YES: 但是原来的网卡配置也是YES,所以修改的方法没有用,尝试了一 ...
- 如何查看显著性SNP在数据中的频率?
我们做完GWAS的关联分析后需要查看显著性SNP在我们数据中的频率分布情况.这时候我们需要用到plink和我们做关系分析所用的二进制文件datas. 第一步,我们用R语言读取分析结果,即*.assoc ...
- JS笔记(二)
1.完整的JavaScript由核心(ECMAScipt).文档对象模型(DOM).浏览器对象模型(BOM)组成. 2.<script>标签的用法:引用位置.src.async.defer ...
- 从苏宁电器到卡巴斯基第23篇:难忘的三年硕士时光 I
初次接触逆向工程 不知不觉就来到了2013年的9月份,学校开学了,我开始正式体验研究生的生活了.按道理来说,硕士研究生是需要围绕在导师身边,每天朝九晚五地去实验室做项目的.不过我们老师没有项目,也不要 ...
- 病毒木马查杀实战第021篇:Ring3层主动防御之编程实现
前言 我们这次会依据上次的内容,编程实现一个Ring3层的简单的主动防御软件.整个程序使用MFC实现,程序开始监控时,会将DLL程序注入到explorer.exe进程中,这样每当有新的进程创建,程序首 ...
- Dalvik模式下基于Android运行时类加载的函数dexFindClass脱壳
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78003184 前段时间在看雪论坛发现了<发现一个安卓万能脱壳方法>这篇 ...
- hdu4932 小贪心
题意: 给了一些处在x轴上的点,要求我们用长度相等的线段覆盖所有点,线段和线段之间不能重叠,问线段最长可以使多长. 思路: 一开始一直在想二分,哎!感觉这个题目很容易就往二分上去 ...
- Photoshop 第二课 工具-钢笔的使用
钢笔的使用 钢笔→ 是一个非常实用(主要用于)但是非常难操作(会者不难哦~)的工具. 钢笔属性中有三种状态:1.路径:2.形状:3.像素.其中路径和形状是我们最常用的状态.路径是一条用来圈定需要操作的 ...
- 【dependencyManagement版本管理】dependencies.dependency.version is missing
maven 的gav的v(版本问题) 报错dependencies.dependency.version is missing 出现的场景 一个项目中有多个模块 父模块中出现dependencies. ...