python迭代器、生成器、yield理解
简介
yield关键字是python的一种高阶用法,使用yield的函数会返回一个生成器对象,生成器又是一个迭代器,与迭代器相类似的则是可迭代对象,下面首先介绍一下迭代器吧。
迭代器
在python中规定,当一个对象里面实现了__iter__、__next__的这两个魔法函数时,则此对象为迭代器。对于迭代器来说,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。
class iter_test(object):
def __init__(self, num):
self.digit = -1
self.num = num
# 返回对象本身
def __iter__(self):
return self
# 返回迭代器的下一个对象
def __next__(self):
# 返回下一个对象
if self.digit < self.num - 1:
self.digit += 1
return self.digit
else:
# 当不存在下一个元素时抛出 迭代异常
raise StopIteration
t = iter_test(10)
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
可迭代对象
实现了__inter__方法并返回迭代器对象(iter,next)的对象就叫做可迭代对象,例如字符串、列表、字典、集合、元组,可迭代对象可以被for循环。
生成器
它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。
yield关键字
在调用生成器函数的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息(保留局部变量),返回yield的值, 并在下一次执行next()方法时从当前位置继续运行,直到生成器被全部遍历完。
例:斐波那契序列
普通写法
def fib(count):
m = 1
n = 1
a = 0
ret = []
while a < count:
ret.append(n)
n, m = m, m+n
a += 1
return ret
for item in fib(6):
print(item)
yield关键字写法,与普通写法类似,只是将列表存储换成了yield,但是会大大减少内存消耗,并且可以使用next进行逐个的结果输出,当实例化对象时,只是创建了一个生成器,只有当进行迭代遍历时才会生成对应对象
def fib2(count):
m = 1
n = 1
a = 0
while a < count:
yield n
n, m = m, m+n
a += 1
fib2 = fib2(6)
print(next(fib2))
print(next(fib2))
print(next(fib2))
print(next(fib2))
yield关键字与return类似,都是执行结果返回,但是return一般为处理完成后返回全部结果,而yield则是在处理过程中暂停当前的运行状态并返回一个结果,且在下次执行时接着上次的执行结果继续执行,内存消耗相对少。
与yield的next函数相关的还有一个send函数
send函数
与next函数功能类似,但send函数可以修改yield 的返回值
def fib3(count):
m = 1
n = 1
a = 0
while a < count:
y_ret = yield n
print(f'y_ret:{y_ret}')
n, m = m, m+n
a += 1
fib3 = fib3(6)
print(fib3.send(None))
print(fib3.send(2))
print(fib3.send(3))
print(next(fib3))
print(next(fib3))
print(next(fib3))
需要注意的是send在获取第一个值时必须传None,send是对上次暂停执行的yield进行赋值,因此,在第一个没到yield时无法传值
yield使用场景
一般而言,对于数据处理时,我们都会存储在一个序列中,但这回消耗较大的内存,yield可以优化这种问题。
yield适用于那种按照特定格式或者逻辑处理的数据,注意返回的是生成器,需要遍历或者next获取元素
- 数据的集合
- 简化代码结构
以上两点都几乎都是基于for循环
yield from
python3.3出现,适用于生成器的嵌套,
yield from 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。
参考
python迭代器、生成器、yield理解的更多相关文章
- Python迭代器生成器与生成式
Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...
- Python入门之迭代器/生成器/yield的表达方式/面向过程编程
本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...
- python 迭代器 生成器
迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- python迭代器生成器
1.生成器和迭代器.含有yield的特殊函数为生成器.可以被for循环的称之为可以迭代的.而可以通过_next()_调用,并且可以不断返回值的称之为迭代器 2.yield简单的生成器 #迭代器简单的使 ...
- Python迭代器生成器,私有变量及列表字典集合推导式(二)
1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getatt ...
- day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包
内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...
- Two---python循环语句/迭代器生成器/yield与return/自定义函数与匿名函数/参数传递
python基础02 条件控制 python条件语句是通过一条或多条语句的执行结果(Ture或者False)来执行的代码块 python中用elif代替了else if,所以if语句的关键字为:if- ...
- Python 迭代器&生成器
1.内置参数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice ...
- (转) Python Generators(生成器)——yield关键字
http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...
- PHP性能优化利器:生成器 yield理解
如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
随机推荐
- 用 Python 为接口测试自动生成用例
用Python为接口自动生成测试用例 基于属性的测试会产生大量的.随机的参数,特别适合为单元测试和接口测试生成测试用例 尽管早在2006年haskell语言就有了QuickCheck来进行" ...
- sklearn机器学习实战-简单线性回归
记录下学习使用sklearn,将使用sklearn实现机器学习大部分内容 基于scikit-learn机器学习(第2版)这本书,和scikit-learn中文社区 简单线性回归 首先,最简单的线性回归 ...
- 开源LIMS系统miso LIMS(适用于NGS基因测序)
开源地址 https://github.com/miso-lims/miso-lims github加速可使用:https://kfqbvpat.fast-github.tk/-----https:/ ...
- 论文解读(AGE)《Adaptive Graph Encoder for Attributed Graph Embedding》
论文信息 论文标题:Adaptive Graph Encoder for Attributed Graph Embedding论文作者:Gayan K. Kulatilleke, Marius Por ...
- Sentinel与OpenFeign 服务熔断那些事
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 sentinel,即可免费获取源码 在上一篇中,我们讲解了 Senti ...
- django框架8
内容概要 ajax简介 前后端传输数据编码格式 ajax发送json格式数据 ajax携带文件数据 回调机制处理策略 内容详情 ajax简介 页面不刷新的情况下可以与后端进行数据交互 异步提交 局部刷 ...
- FlinkSQL源码阅读-schema管理
在Flink SQL中, 元数据的管理分为三层: catalog-> database-> table, 我们知道Flink SQL是依托calcite框架来进行SQL执行树生产,校验,优 ...
- c++ 超大整数除法 高精度除法
c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...
- Linux(Centos7)静默安装Oracle19C
Oracle数据库服务器一般都是Linux,Linux服务器一般都是在非图形界面的操作,本文章手把手教你如何在非图形界面安装Oracle19C. ORACLE 19C 的安装包自行在官网下载,下载免费 ...
- springboot整合ueditor实现图片上传和文件上传功能
springboot整合ueditor实现图片上传和文件上传功能 写在前面: 在阅读本篇之前,请先按照我的这篇随笔完成对ueditor的前期配置工作: springboot+layui 整合百度富文本 ...