简介

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 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。

参考

yield理解

yield使用场景

最新文章

  1. history命令详解
  2. Bootstrap分为几部分?
  3. cf Canada cup A题
  4. Getting Started With Hazelcast 读书笔记(第四章)
  5. 将字符串拆分为id
  6. PHP API 框架开发的学习
  7. git学习笔记08-分支管理策略-实际上我们应该怎么应用分支
  8. c#配置log4net步骤
  9. 使用exe4j把JAVA GUI程序打包成exe文件时遇到的问题
  10. weblogic集群无法启动,提示java.lang.NumberFormatException
  11. 记一次排查log4net 不输出日志的解决过程
  12. Java设计模式菜鸟系列(九)外观模式建模与实现
  13. Vmdk文件如何使用,vmdk导入虚拟机VMware8.0教程
  14. React-Native入门
  15. Intellij IDEA 建立文件夹目录问题
  16. JDK+Tomcat+Zookeeper+DubboAdmin安装教程
  17. 知识点---js监听手机返回键,回到指定界面
  18. zepto的extend
  19. php判断是否为命令行模式
  20. MySQL之库、表操作

热门文章

  1. 使用BGP-blackhole解决IDC频繁遭受DDOS攻击困扰
  2. HMS Core使能AI智慧体验,共建创新应用生态
  3. docker-compose 启动 rabbitmq
  4. Java面试宝典学习笔记【2020】
  5. 对于vjudge在有些网络下无法打开的问题
  6. 【JSOI2016】最佳团体
  7. ACM 刷题记录
  8. Python Selenium库
  9. Node.js安装与环境配置
  10. Java开发学习(四)----bean的三种实例化方式