博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[译]yield关键字都做了什么?
阅读量:5990 次
发布时间:2019-06-20

本文共 1902 字,大约阅读时间需要 6 分钟。

原文:

我的微信公众号:python每日一练

要理解什么是 yield,必须理解什么是生成器(generator)。在理解生成器之前,让我们先了解迭代。

迭代

当你建立了一个列表,你可以逐个地访问这个列表的元素,而这个访问的过程叫做迭代(iteration)

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

代码中的mylist就是一个可迭代对象(iterable),当你使用列表生成式时,你就创建了一个list,同时也创建了一个可迭代对象:

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

凡是能使用for...in...语句的对象,都叫做可迭代对象,例如:liststring、文件等等

这些可迭代对象非常方便,因为你可以根据自己的需要来访问它们。但是同时也需要将所有的值存入内存当中,无论你是不是需要所有的值,可能对于一个列表[x for x in range(100000)],你仅仅想拿到里面的素数,但当这个列表生成式被执行的时候,已经将所有100000个数字存入了内存中。

生成器

生成器是一种只能迭代一次的迭代器,生成器不会一次将所有的元素存入内存中,而是一边迭代一边运算:

>>> mygenerator = (x*x for x in range(3))>>> for i in mygenerator:...    print(i)014

这份代码看起来和上面的代码没有什么区别。但是你不能再次执行for i in mygenerator,因为生成器只能使用一次:

>>> mygenerator = (x*x for x in range(3))>>> for i in mygenerator:...     print(i)...014>>> for i in mygenerator:...     print(i)...>>>

Yield

yield的使用和return的使用没什么区别,只是yield会返回一个生成器

>>> def createGenerator():...    mylist = range(3)...    for i in mylist:...        yield i*i...>>> mygenerator = createGenerator() # 创建一个生成器>>> print(mygenerator) # mygenerator是一个对象!
>>> for i in mygenerator:... print(i)014

当你的函数需要返回一个很大的元素集合,并且每个元素只需要用到一次的时候,使用yield会非常方便

要想理解yield,你必须理解当你调用一个包含yield的函数的时候,函数体代码并不会执行,这个函数仅仅是返回一个生成器而已

>>> def createGenerator():...     print('head')...     for i in range(5):...         yield i*i...     print('tail')...>>> createGenerator()

当你第一次向后迭代(用nextfor...in...语句时)这个生成器时,函数体才会从最开始执行到yield处然后返回yield的值,随后再次向后迭代,会执行剩余的代码然后再次遇到yield停止并返回值。直到运行到函数结尾处停止,此时如果是用next()则会抛出StopIteration异常,如果是用for...in...则会结束循环并且不会有异常

>>> def createGenerator():...     print('head')...     for i in range(5):...         yield i*i...     print('tail')...>>> g = createGenerator()>>> next(g)head0>>> next(g)1>>> next(g)4>>> next(g)9>>> next(g)16>>> next(g)tailTraceback (most recent call last):  File "
", line 1, in
StopIteration

转载地址:http://hpnlx.baihongyu.com/

你可能感兴趣的文章
HTTP协议header中Content-Disposition中文文件名乱码
查看>>
PostgreSQL Oracle 兼容性之 - add_months
查看>>
CentOS6.5菜鸟之旅:U盘安装CentOS64位
查看>>
史上最牛逼的纯CSS实现tab选项卡,闪瞎你的狗眼
查看>>
阿里·云效俱乐部会员招募
查看>>
SpriteBuilder中音频波长超过Timeline结尾的情况
查看>>
阿里宣布开源Weex,用Web方式开发Native性能体验应用
查看>>
《Netty 权威指南》—— AIO创建的TimeClient源码分析
查看>>
Spark独立模式
查看>>
使用svd()对矩阵奇异值分解(singular value decomposition)
查看>>
Android中的线程池与任务队列
查看>>
深入TCP/IP协议---网络层详解(1)
查看>>
浏览器闪烁页面标题进行提醒(转载)
查看>>
徒手生撸教你如何解锁React-Native史诗级成就“Hello World”
查看>>
click事件的累加及解决方式
查看>>
「docker实战篇」python的docker爬虫技术-fiddler抓包工具(三)
查看>>
【今日头条】【抖音&火山】算法实习生
查看>>
java流的中间操作源码解析
查看>>
Android开发 - 掌握ConstraintLayout(二)介绍
查看>>
EOS开发完全解析(一):Ubuntu上搭建EOS开发环境
查看>>