[PY3]——函数——生成器(yield关键字)
函数—生成器篇
1. 认识和区分可迭代or生成器
1.1 可迭代对象
当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象
当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代的对象
所有可以使用 for..in..语法的叫做一个迭代器:例如列表,字符串,文件……
经常使用它们是因为我们可以如愿的读取其中的元素,但是你把所有的值都存储到了内存中,如果你有大量数据的话这个方式并不是你想要的
mylist=[ x*x for x in range(3) ]
for i in mylist:
print(i) for i in mylist:
print(i)
0
1
4
0
1
1.2 生成器
生成器是可以迭代的,但是你只可以读取它一次,因为它并不把所有的值放在内存中,它是实时地生成数据
mygenerator=( x*x for x in range(3) )
for i in mygenerator:
print(i) for i in mygenerator:
print(i) 0
1
4
2. 理解生成器 & yield
2.1 生成器是惰性求值的
惰性求值也叫延迟求值,顾名思义就是表达式不会在它被绑定到变量之后就立即求值,而是等用到时再求值。 延迟求值的一个好处是能够建立可计算的无限列表而没有妨碍计算的无限循环或大小问题。 考虑到yield的特性:可在减少内存占用、避免使用递归等场景时选择yield
2.2 生成器函数的执行流程
# yield关键字的作用是把一个函数变成一个generator,称为生成器函数。
# 生成器函数的返回值是生成器
* 生成器函数执行的时候,不会执行函数体
* 当next生成器的时候, 当前代码执行到之后的第一个yield,会弹出值,并且暂停函数
* 当再次next生成器的时候,从上次暂停处开始往下执行
* 当没有多余的yield的时候,会抛出StopIteration异常,异常的value是函数的返回值
通过以下例子来理解generator执行流程:
def gen(x):
if x!=0:
yield x mygenerator=gen(3) print(mygenerator) #当我们调用这个函数时,我们发现函数内部的代码并不立马执行,而只是返回了一个生成器对象
#<generator object gen at 0x7f63ee065888> for i in mygenerator: #当你使用for进行迭代时,函数内的代码才执行
print(i)
#3 print(next(mygenerator)) #或者使用next()
#3
def gen(max): # def gen():
a,b=1,1 # do something (a)
while a<max:
yield a # yield a # (b)
a,b=b,a+b # do something (c) for n in gen(15): # for n in gen():
print(n) # do something with n (d)
def dedupe(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item) a = [1, 5, 2, 1, 9, 1, 5, 10]
for n in dedupe(a):
print(n)
1
5
2
9
10 执行大致过程(个人理解,有误请指正):
seen=set( ) 生成器环境初始化
|
dedupe内的for循环
|
调用yield item=1
|
print 1
|
add 1
|
dedupe内的for循环
|
调用yield item=5
|
print 5
|
add 5
|
dedupe内的for循环
|
调用yield item=2
|
print 2
|
add 2
|
dedupe内的for循环('1'已经在items里所以不执行循环)
|
dedupe内的for循环
|
调用yield item=9
|
......
def gen():
print('a')
yield 1
print('b')
yield 2
return 3 g=gen() print(g)
#<generator object gen at 0x7f144845a308> print(next(g))
#a
#1 print(next(g))
#b
#2 print(next(g))
#StopIteration: 3
3. 生成器作用场景
3.1 计数器的例子
# version-1
def counter():
x=0
while True:
x+=1
yield x def inc(x):
return next(x) # version-2
def counter():
x=0
while True:
x+=1
yield x def inc():
c=counter()
return lambda :next(c) # version-3
def make_inc():
def counter():
x=0
while True:
x+=1
yield x
c=counter()
return lambda :next(c) ## 为什么这里不直接 return next(c) ##
def make_inc():
def counter():
x=0
while True:
x+=1
yield x
c=counter()
return lambda :next(c)
# return lambda:next(c)的运行结果
incr=make_inc()
print(id(incr())) #取1
#8939648
print(id(incr())) #取2
#8939680 def make_inc():
def counter():
x=0
while True:
x+=1
yield x
c=counter()
return next(c)
# return next(c)的运行结果
print(id(make_inc())) #取1
#8939648
print(id(make_inc())) #取1
#8939648
3.2 解决递归问题 — 生成斐波那契数列的例子
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b
n+=1 for n in fib(5):
print(n) 1
1
2
3
5
3.3 协程 —— 生成器的高级用法
进程、线程 ——在内核态调度的
协程 ——在用户态调度(即用户自己写调度器)
——运行在一个线程之内,所以也被叫做轻量线程
——非抢占式调度
调度 ——简单的说就是由调度器来决定哪段代码占用cpu时间 协程在python3已经进入标准库了 ——asyncio
python3.5 中加入了 asyn、 await延伸支持
参考文章
《Python yield使用浅析-廖雪峰(含通过yield实现文件读取的方法)》
《[译]python关键字yield的解释(stackoverflow)》
[PY3]——函数——生成器(yield关键字)的更多相关文章
- (转) Python Generators(生成器)——yield关键字
http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...
- 理解 ES6 语法中 yield 关键字的返回值
在 ES6 中新增了生成器函数的语法,本文解释了生成器函数内 yield 关键字的返回值. 描述 根据语法规范,yield 关键字用来暂停和继续执行一个生成器函数.当外部调用生成器的 next() 方 ...
- PHP性能优化利器:生成器 yield理解
如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
- Python:笔记(7)——yield关键字
Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...
- PHP 生成器 yield理解
如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
- py3.0第四天 函数,生成器迭代器等
1.列表生成式,迭代器&生成器 孩子,我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1,你怎么实现?你可能会想到2种方式 > ...
- ES6学习笔记<三> 生成器函数与yield
为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...
- Python:容器、迭代对象、迭代器、生成器及yield关键字
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list, ...
- day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包
内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...
随机推荐
- Monthly数据类型
Monthly由来 最近在做关于智能财税的项目,大量用到了账期相关的数据操作.项目已有两年历史了,对于账期数据,前辈们用的是DateTime数据类型,即每个月的最后一天就是账期.而用DateTime来 ...
- ASP.NET MVC学习目录
一.ASP.NET MVC原理详解 1.了解MVC架构模式 3.学习ASP.NET MVC的必备语言知识 4.MVC中的razor语法详解 5.ASP.NET MVC路由系统机制详细讲解 6.ASP. ...
- python--生成器,生成器推导式, yield from
一.生成器 生成器的本质就是迭代器,它一个一个的创建对象. 在python中有三种方式获取生成器: 1.通过生成器函数 2.通过各种推导式来实现生成器 3.通过数据的类型转换也可以获取生成器 二.生成 ...
- NOIP2018滚粗祭(周记更新至11.25)
还好吧, 好像回归之后 还是有时间去机房转一转的 一个特别生动的例子就是 体育会考就去机房呆了一上午. 这里又要吐槽一下信息技术会考 stm我拿到的第一道题就是 https://www.luogu ...
- [SQL] 简单新建(create)删除(drop\delete)权限(grant/revoke)修改(set\update)
一.前言 说起来 数据库(Structured Query Language),本站写过很多类似文章. 如: Mysql创建.删除用户 phpMyAdmin 登陆需要密码 记一次裸迁 MySQL 经历 ...
- [真题] 一道 vsftp 运维题
一道 vsftp 运维题 一.前言 在 V 站上凑巧看到了好友发的求助帖,五天时间一个理他的都没有.哈哈哈~ 废话不多说,我们来试试. 二.题目 这里我们假设存在这样的场景: 网络内有普通用户 ade ...
- HTML实例(四)
实例一:有序列表,无序列表,<dl>,<dt>,<dd>,div块级标签等,实现上面的效果. <!DOCTYPE html> <html lang ...
- python 之 比较哪个数据大小
#定义一个字典info={}#定义比较的人数n=int(input("请输入你要比较的人数"))#循环while(n): #输入a,b 两个数据 ,分别代表学号 和分数 # 把输入 ...
- day03 --class --homework
'''# >>>>>>2 :,有字符串s = "123a4b5c"#>>>>>^ 1: # 1)通过对s切片形成新 ...
- hive连接mysql遇到的问题
启动hive之前应该先启动metastore,也是在bin目录下:./hive --service metastore &然后再启动hive: ./hive 今天连接hive时总是报错:Una ...