欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

[译]yield关键字都做了什么?

发布时间:2025/4/16 编程问答 6 豆豆
生活随笔 收集整理的这篇文章主要介绍了 [译]yield关键字都做了什么? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
原文:https://stackoverflow.com/que...

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

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

迭代

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

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

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

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

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

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

生成器

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

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

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

>>> mygenerator = (x*x for x in range(3)) >>> for i in mygenerator: ... print(i) ... 0 1 4 >>> 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是一个对象! <generator object createGenerator at 0xb7555c34> >>> for i in mygenerator: ... print(i) 0 1 4

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

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

>>> def createGenerator(): ... print('head') ... for i in range(5): ... yield i*i ... print('tail') ... >>> createGenerator() <generator object createGenerator at 0x0000023454FB5990>

当你第一次向后迭代(用next或for...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) head 0 >>> next(g) 1 >>> next(g) 4 >>> next(g) 9 >>> next(g) 16 >>> next(g) tail Traceback (most recent call last):File "<stdin>", line 1, in <module> StopIteration

总结

以上是生活随笔为你收集整理的[译]yield关键字都做了什么?的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。