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才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
随机推荐
- vscode修改括号对颜色,自定义括号颜色
新版的vscode 1.67(2022年4月更新的版本),自带括号颜色匹配,十分的方便. 至于怎么开启,已经有人写过,这里就不写了,更新到新版默认开启~ 括号颜色默认只有3种颜色,有时候感觉不够用. ...
- 890. Find and Replace Pattern - LeetCode
Question 890. Find and Replace Pattern Solution 题目大意:从字符串数组中找到类型匹配的如xyy,xxx 思路: 举例:words = ["ab ...
- Spring-Batch将CSV文件转为XML文件
1 介绍 用Spring Batch实现一个简单的需求,将csv文件转换成xml文件. csv文件如下:record.csv username, user_id, transaction_date, ...
- CF1682F MCMF?
题意: 费用流,其实bushi 给你长为\(n\)的序列\(a\),\(b\).\(a\)单增,\(b\)有正有负. \(q\)次询问\([l,r]\),保证\(\sum\limits_{i=l}^r ...
- MTK 虚拟 sensor bring up (pick up) sensor1.0
pick up bring up sensor1.0 1.pick up对比 2.SCP 1.添加驱动文件 2.添加编译环境(打开开关) 注:编译过程中如果显示内存不够 3.修改底层数据上报方式 3. ...
- Spring AOP快速使用教程
Spring是方法级别的AOP框架,我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应的AOP通知.为了更方便的测试我们首先创建一个接口 public in ...
- net core天马行空系列-可用于依赖注入的,数据库表和c#实体类互相转换的接口实现
1.前言 hi,大家好,我是三合.作为一名程序猿,日常开发中,我们在接到需求以后,一般都会先构思一个模型,然后根据模型写实体类,写完实体类后在数据库里建表,接着进行增删改查, 也有第二种情况,就是有些 ...
- HTML,CSS,JS,DOM,jQuery
HTML 超链接访问顺序 a:link-->a:visited-->a:hover-->a:active.(有顺序) link:表示从未访问过的链接的样式 visited:表示已经访 ...
- UiPath邮件自动化
在UiPath中下载Outlook电子邮件附件Outlook电子邮件自动化教程UiPathRPAhttps://www.bilibili.com/video/BV1oK411L72T 在UiPath中 ...
- 正在运行中的docker容器设置自动重启
# demo : 你的容器名称 docker update –-restart=always demo