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才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
随机推荐
- PHP反序列化链分析
前言 基本的魔术方法和反序列化漏洞原理这里就不展开了. 给出一些魔术方法的触发条件: __construct()当一个对象创建(new)时被调用,但在unserialize()时是不会自动调用的 __ ...
- MySQL字段约束条件、字段类型、存储引擎、配置文件
字符编码与配置文件 # 查看MySQL默认字符编码 \s ''' 如果是5.X系列 显示的编码有很多种 Latin1 gbk 如果是8.X系列 显示的统一是utf8mb4 utf8mb4是utf8优化 ...
- .NET混合开发解决方案13 自定义WebView2中的上下文菜单
系列目录 [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...
- Java 16 新特性:record类
以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类.record关键词的引入,主要是为了提供一种更为简洁.紧凑的final类的定义方式. ...
- JUC自定义线程池练习
JUC自定义线程池练习 首先上面该线程池的大致流程 自定义阻塞队列 首先定义一个双向的队列和锁一定两个等待的condition 本类用lock来控制多线程下的流程执行 take和push方法就是死等, ...
- 栈在go语言中实现,及解决388.文件的最长绝对路径的思路
今天在LeetCode刷每日一题,遇到了388. 文件的最长绝对路径的思路,这道题让我想到了系统的目录是栈结构,果然在题解中找到了栈的解法(暴力半天没出来,跑去看题解了QWQ). 所以我就捎带复习了一 ...
- Sentinel介绍与使用 收藏起来
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 sentinel,即可免费获取源码 前言 在家休息的的时候,突然小勇打 ...
- forms组件补充与ModelForm简单使用与cookie与session
目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...
- 降维、特征提取与流形学习--非负矩阵分解(NMF)
非负矩阵分解(NMF)是一种无监督学习算法,目的在于提取有用的特征(可以识别出组合成数据的原始分量),也可以用于降维,通常不用于对数据进行重建或者编码. NMF将每个数据点写成一些分量的加权求和(与P ...
- 认识弹性盒子flex
认识弹性盒子flex 来源:https://blog.xybin.top/2022/flex 1.定义弹性布局(父级上定义)display:flex; 如果说内核为webkit 的必须前面加上 -we ...