浅析Python中yield关键词的作用与用法

yipeiwu_com5年前Python基础

前言

为了理解yield是什么,首先要明白生成器(generator)是什么,在讲生成器之前先说说迭代器(iterator),当创建一个列表(list)时,你可以逐个的读取每一项,这就叫做迭代(iteration)。

>>> mylist = [1, 2, 3]
>>> for i in mylist :
... print(i)
1
2
3

mylist 是一个可迭代的对象。当使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代的对象:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist :
... print(i)
0
1
4

可以使用“for··· in ··· ”来操作可迭代对象,如:list,string,files,这些迭代对象非常方便我们使用,因为你可以按照你的意愿进行重复的读取。但是你不得不预先存储所有的元素在内存中,那些对象里有很多元素时,并不是每一项都对你有用。

生成器同样是可迭代对象,但是你只能读取一次,因为它并没有把所有值存放内存中,它动态的生成值:

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator :
... print(i)
0
1
4

看起来除了把 [] 换成 () 外没什么不同。但是,你不可以再次使用 for i in mygenerator , 因为生成器只能被迭代一次:先计算出0,然后继续计算1,然后计算4,一个跟一个…

yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器。

>>> def createGenerator() :
... mylist = range(3)
... for i in mylist :
...  yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...  print(i)
0
1
4

这个示例本身没什么意义,但是它很清晰地说明函数将返回一组仅能读一次的值,要想掌握yield,首先必须理解的是:当你调用生成器函数的时候,如上例中的createGenerator() ,程序并不会执行函数体内的代码,它仅仅只是返回生成器对象,这种方式颇为微妙。函数体内的代码只有直到每次循环迭代(for)生成器的时候才会运行。

第一次迭代中你的函数会执行,从开始到达 yield 关键字,然后返回 yield 后的值作为第一次迭代的返回值. 然后,每次执行这个函数都会继续执行你在函数内部定义的那个循环的下一次,再返回那个值,直到没有可以返回的。

如果生成器内部没有定义 yield 关键字,那么这个生成器被认为成空的。这种情况可能因为是循环进行没了,或者是没有满足 if/else 条件。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能有所帮助,如果有疑问大家可以留言交流。

相关文章

Python编程学习之如何判断3个数的大小

前言 大部分初学编程的人来说刚开始都会练习判断两个数或者三个数的大小,来熟悉某种语言的特性和最基本的if,else循环,当我们学习了更高级的语法知识后,又会有不同的实现方式,比如这道练习...

Python模拟百度登录实例详解

最近公司产品和百度贴吧合作搞活动,为了增加人气,打算做个自动签到的小程序。这个是测试登录的代码,写的比较随意,仅实现了登录并读取关注贴吧列表,下边的就比较简单。 百度登录还是有点麻烦的,...

用Python从零实现贝叶斯分类器的机器学习的教程

用Python从零实现贝叶斯分类器的机器学习的教程

朴素贝叶斯算法简单高效,在处理分类问题上,是应该首先考虑的方法之一。 通过本教程,你将学到朴素贝叶斯算法的原理和Python版本的逐步实现。 更新:查看后续的关于朴素贝叶斯使用技巧的文章...

Python imageio读取视频并进行编解码详解

读视频和写视频一直由于编解码的问题给程序员造成很多麻烦。对此进行了一些探索。用Python读取视频有两种主要方法,分别是基于imageio库和OpenCV,其中OpenCV加上ffmpe...

Python中正则表达式的用法总结

正则表达式很神奇啊 # -*- coding:utf-8 -*- import re def print_match_res(res): """打印匹配对象内容""" if...