简介

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使用场景

python迭代器、生成器、yield理解的更多相关文章

  1. Python迭代器生成器与生成式

    Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...

  2. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  3. python 迭代器 生成器

    迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  4. python迭代器生成器

    1.生成器和迭代器.含有yield的特殊函数为生成器.可以被for循环的称之为可以迭代的.而可以通过_next()_调用,并且可以不断返回值的称之为迭代器 2.yield简单的生成器 #迭代器简单的使 ...

  5. Python迭代器生成器,私有变量及列表字典集合推导式(二)

    1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getatt ...

  6. day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包

    内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...

  7. Two---python循环语句/迭代器生成器/yield与return/自定义函数与匿名函数/参数传递

    python基础02 条件控制 python条件语句是通过一条或多条语句的执行结果(Ture或者False)来执行的代码块 python中用elif代替了else if,所以if语句的关键字为:if- ...

  8. Python 迭代器&生成器

    1.内置参数     Built-in Functions     abs() dict() help() min() setattr() all() dir() hex() next() slice ...

  9. (转) Python Generators(生成器)——yield关键字

    http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...

  10. PHP性能优化利器:生成器 yield理解

    如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...

随机推荐

  1. 使用C#跨PC 远程调用程序并显示UI界面

    在项目中有一个需求是需要在局域网内跨PC远程调用一个程序,并且要求有界面显示,调查了一些资料,能实现远程调用的.Net技术大概有PsExec.WMI.Schedule Task. 这三种方式都做了一个 ...

  2. java_简单学习笔记

    java_study笔记 前言: 所有笔记均总结自狂神的java基础视频 https://www.bilibili.com/video/BV12J41137hu?p=1 idea小技巧 psvm+回车 ...

  3. drools中query的使用

    一.背景 我们知道在drools中是存在工作内存的,我们的Fact对象会加入到工作内存中,同时我们自己也可以在drl文件中使用insert/modify/update/delete等方法,修改工作内存 ...

  4. SSE图像算法优化系列三十二:Zhang\Guo图像细化算法的C语言以及SIMD指令优化

    二值图像的细化算法也有很多种,比较有名的比如Hilditch细化.Rosenfeld细化.基于索引表的细化.还有Opencv自带的THINNING_ZHANGSUEN.THINNING_GUOHALL ...

  5. 如何在Uniapp中访问CabloyJS后端API管理系统

    介绍 CabloyJS是一款免费开源的NodeJS全栈开发框架,采用前后端分离设计,具备开箱即用的后台管理系统 Cabloy-SDK是专门为Uniapp应用量身定制的前端SDK,用于便捷的访问Cabl ...

  6. UVA471 Magic Numbers 题解

    1.题目 题意很简单:输入n,枚举所有的a,b,使得 (1)满足a/b=n. (2)满足a,b各个位上的数字不相同. 2.思路 (1)对于被除数,要满足各个位上的数字,显然最大枚举到987654321 ...

  7. CSRF跨站请求伪造与XSS跨域脚本攻击讨论

    今天和朋友讨论网站安全问题,聊到了csrf和xss,刚开始对两者不是神明白,经过查阅与讨论,整理了如下资料,与大家分享. CSRF(Cross-site request forgery):跨站请求伪造 ...

  8. 关于Node.js 链接mysql超时处理(默认8小时)

    备注:这是在pm2配置node环境下,超过8小时mysql自动关闭的情况下出现的解决方法:1.封装mysql.js var mysql = require('mysql'); var connecti ...

  9. 从开发一款基于Vue技术栈的全栈热重载生产环境脚手架,我学到了什么

    浏览文章前 这一期,我分享给大家三点看源码的小技巧,这也是从别的大佬那总结的. 被反复使用的代码 这样的代码是一个软件的重点函数,一个大神的写法有很多精华值得学习. 穿越时间的代码 如果一段代码10年 ...

  10. Moriis神级遍历!

    Moriis 遍历 Morris 遍历是二叉树遍历的一种方式,传统的递归和非递归遍历的时间复杂的都是O(N),空间复杂度都是O(h)(h为树的高度),而 Morris 遍历可以做到时间复杂的依然为 O ...