python记录_day12 生成器
什么是生成器?
生成器的实质就是迭代器,我们能够从生成器中一个一的拿值
python中获取生成器的方式有三种:
1、通过生成器函数
2、通过生成器表达式
3、通过数据转换也可以获取生成器(某些对象执行一个方法就能返回一个生成器,这个现在用不到)
一、 生成器函数
def gen():
代码块
yield 返回值 gen() #表示获取一个生成器,是一个内存地址,装的是代码,并不执行,用的时候才会执行
将return换成yield就是生成器函数了,上面就是生成器函数的格式。yield的作用是代码执行到这里就会停止,并且会返回一个值,所以代码能够分段执行,这就是生成器能逐个拿值的原因。
对于生成器函数,函数名+()并不表示函数执行,而是获取一个生成器对象。生成器装的是代码,只有在需要拿值的时候才会执行,这是生成器的惰性机制。
1、通过__next__访问生成器
# def gen():
# print("娃哈哈")
# yield '爽歪歪'
# print("酸酸乳")
# yield 'AD钙奶'
# print('黄焖鸡米饭')
#
# ret = gen() #获取生成器对象,生成器装的是代码,要的时候运行一段
# print(ret) #<generator object gen at 0x0000000001E12F10> 生成器 generator
# print(ret.__next__()) #调用__next__才会执行,返回爽歪歪
# print(ret.__next__()) #调用__next__才会执行,返回Ad钙奶
#print(ret.__next__()) #StopIteration 迭代器,就找yield,找不到就会报错 往下运行,打印出了“黄焖鸡米饭”,但是找不到yield,所以报错
__next__()
2、通过send()访问生成器
send()可以取值的同时给上一个yield位置传值
def func():
print("水饺")
a = yield "大馅水饺"
print("a=", a)
print("烧饼")
b = yield "武大郎烧饼"
print("b=", b)
print("老婆饼")
c = yield "只要老婆不要饼"
print("c =",c) g = func()
print("返回值是:",g.__next__())
print("返回值是:",g.send("面条"))
print("返回值是:",g.send("面条"))
#print("返回值是:",g.send("面条")) #c = 面条 报错 StopIteration #结果
水饺
返回值是: 大馅水饺
a= 面条
烧饼
返回值是: 武大郎烧饼
b= 面条
老婆饼
返回值是: 只要老婆不要饼
send()
send和__next__的区别:
send()和__next__都可以让生成器向下走一段,但send可以给上一个yield位置传值,使用时不能在第一次,也不能给最后一个yield传值
二、推导式
1、列表推导式
语法:[ 结果 for循环 if判断 ]
lst = ["中岛美雪","夏川美里","原由子","汪峰","田震","那英","周杰伦"] l = [name for name in lst if len(name) == 2 ] #这就是列表推导式
print(l)
2、字典推导式
语法:{ key:value for循环 if判断 }
dic ={"张无忌":"赵敏","杨过":"小龙女","郭靖":"黄蓉"}
new_dic = {dic[k]: k for k in dic} #字典推导式
print(new_dic)
new = {v:k for k,v in dic.items()} #字典推导式
print(new)
字典推导式
3、集合推导式
语法:{ 结果 for循环 if判断 }
lst = [1,2,3,1,2,4]
se = {k for k in lst} #这是集合推导式
print(se) # {1,2,3,4}
集合推导式自带去重功能
5、没有元组推导式
6、生成器表达式
语法:( 结果 for循环 if判断 )
names = [['Tom',"Billy","Jefferson","Abdrew","Wesley","Steven","Joe"],['Alice',"Jill","Ana","Wendy",'Jennifer','Sherry','Eva']] name_gen = (name for el in names for name in el if name.count("e")==2)
print(name_gen.__next__())
print(name_gen.__next__())
print(name_gen.__next__()) 结果
#Jefferson
#Wesley
#Steven
生成器表达式
生成器拿值方式:
1、用__next__和send
2、使用for循环
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)
3、list(g),g是生成器
gen = (i * i for i in range(100) if i % 3 == 0)
print(list(gen))
结果是一个列表
[0, 9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304, 2601, 2916, 3249, 3600, 3969, 4356, 4761, 5184, 5625, 6084, 6561, 7056, 7569, 8100, 8649, 9216, 9801]
生成器的特性:
1、节省内存
2、惰性机制 (不到最后使用时不会拿值)
3、拿值只能往前,不能后退
惰性机制+只能往前拿值特性的组合考察(深坑):
def func():
print(111)
yield 222
g = func() # 生成器g
g1 = (i for i in g) # 生成器g1. 但是g1的数据来源于g
g2 = (i for i in g1) # 生成器g2. 来源g1
print(list(g)) # 获取g中的数据. 这时func()才会被执行. 打印111.获取到222. g完毕.
print(list(g1)) # 获取g1中的数据. g1的数据来源是g. 但是g已经取完了. g1 也就没有数据
了
print(list(g2)) # 和g1同理 #结果
111
222
[]
[]
**小知识 yield from**
yield ffrom 可以直接把可迭代对象中的每一个数据作为生成器的结果进行返回
def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
yield from lst g = gen() #获取生成器
for el in g:
print(el) 等价于:
def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
yield lst[0]
yield lst[0]
yield lst[0]
yield lst[0]
g = gen() #获取生成器
for el in g:
print(el)
yield from
**面试题**
1、
def gen():
lst = ["花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
yield from lst #yield from 会迭代返回列表中的元素,执行完lst才会执行lst2,所以不会有交替打印的效果
yield from lst2
g = gen()
for el in g:
print(el)
效果:
花藤
胡辣汤
微星牌饼铛
Mac牌锅铲
饼铛还是微星的好
联想不能煮鸡蛋
微星就可以
还可以烙饼
2、
def add(a,b):
return a + b
def test():
for r_i in range(4):
yield r_i
g = test()
for n in [2,10]:
g = (add(n,i) for i in g)
print(list(g))
#for循环第一次执行,n= 2时 g变为了 g = add(n,i) for i in (add(n,i) for i in test() 这时没取值,g也就不执行
# for第二次执行,n=10 此时 g= add(n,i) for i in (add(n,i) for i in test() 这时开始取值 ,g执行 结果:
[20, 21, 22, 23]
python记录_day12 生成器的更多相关文章
- python高级之生成器&迭代器
python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...
- 第三篇:python高级之生成器&迭代器
python高级之生成器&迭代器 python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container ...
- 十二. Python基础(12)--生成器
十二. Python基础(12)--生成器 1 ● 可迭代对象(iterable) An object capable of returning its members one at a time. ...
- Python三大器之生成器
Python三大器之生成器 生成器初识 什么是生成器 生成器本身属于迭代器.继承了迭代器的特性,惰性求值,占用内存空间极小. 为什么要有生成器 我们想使用迭代器本身惰性求值的特点创建出一个可以容纳百万 ...
- Python函数04/生成器/推导式/内置函数
Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...
- 【python】迭代器&生成器
源Link:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素 ...
- python中的生成器函数是如何工作的?
以下内容基于python3.4 1. python中的普通函数是怎么运行的? 当一个python函数在执行时,它会在相应的python栈帧上运行,栈帧表示程序运行时函数调用栈中的某一帧.想要获得某个函 ...
- 十三. Python基础(13)--生成器进阶
十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...
- Python学习-39.Python中的生成器
先回顾列表解释 lista = range(10) listb = [elem * elem for elem in lista] 那么listb就将会是0至9的二次方. 现在有这么一个需求,需要存储 ...
随机推荐
- Docker 使用Docker-Compose编排容器
简介: Docker Compose是一个用来定义和运行复杂应用的Docker工具.一个使用Docker容器的应用,通常由多个容器组成.使用Docker Compose不再需要使用shell脚本来启动 ...
- 颠倒的价牌|2013年蓝桥杯A组题解析第四题-fishers
颠倒的价牌 小李的店里专卖其它店中下架的样品电视机,可称为:样品电视专卖店. 其标价都是4位数字(即千元不等). 小李为了标价清晰.方便,使用了预制的类似数码管的标价签,只要用颜色笔涂数字就可以了(参 ...
- What are the differences between Flyweight and Object Pool patterns?
What are the differences between Flyweight and Object Pool patterns? They differ in the way they are ...
- hihoCoder week14 无间道之并查集
并查集的基本使用 #include <bits/stdc++.h> using namespace std; ; int n, fa[N]; int cnt, tot; map<st ...
- Restructure output of R summary function
Treat it as a data.frame: set.seed(1)x <- sample(30, 100, TRUE) summary(x)# Min. 1st Qu. Medi ...
- Oracle 之 函数运用
NVL函数:NVL(a,b)就是判断a是否是NULL,如果不是返回a的值,如果是返回b的值 通过查询获得某个字段的合计值,如果这个值位null将给出一个预设的默认值 通过nvl 对定义值赋值的语法: ...
- module.exports 与 exports
module.exports 与 exports 注意:1 对于要导出的属性,可以简单直接挂到 exports 对象上2 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用 new 操作符创建 ...
- springboot集成logback日志
简介 spring boot内部使用Commons Logging来记录日志,但也保留外部接口可以让一些日志框架来进行实现,例如Java Util Logging,Log4J2还有Logback. 如 ...
- 封装fetch的使用(包含超时处理)
// 1: 传统fetch操作 fetch('http://facebook.github.io/react-native/movies.json') .then((response) => r ...
- Vue--获取数据
一.Jsonp抓取数据 用 npm 安装 jsonp npm install jsonp 创建 jsonp.js import originJsonp from 'jsonp' export defa ...