ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python生成器(generator)--yield的使用

2021-10-04 16:58:44  阅读:159  来源: 互联网

标签:函数 generator Python 生成器 yield next 迭代


文章目录

前言

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

调用一个生成器函数,返回的是一个迭代器对象。

一、yield是什么?

  • 可以把yield看成和return类似的返回值。但yield又和return有很大不同之处。
  1. yield与return的相同之处:
    都是在函数中第一次遇见yield/return就返回其后面的值。
  2. yield与return不同之处:
    1.带有yield的函数不再是一个普通的函数,而是一个生成器(generator)。用于迭代
    2.与带有return的普通函数不同。调用带有yield的函数(生成器)时不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。即用的时候(迭代时)才生成。
    3.yield 是一个类似 return 的关键字,每迭代一次遇到yield时就返回yield后面的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码开始执行。第一次调用时必须先next(),否则会报错。

生成器(generator):可以看成一个能够迭代的list。可以执行next()函数,直到捕获到第一个异常后终止(即迭代完所有元素)。
谷歌解释:所谓生成器函数, 就是每当它执行一次生成(yield)语句, 它就返回一个迭代器, 这个迭代器生成一个值. 生成值后, 生成器函数的运行状态将被挂起, 直到下一次生成.
注:在for … in …中默认会执行next()函数。

yield的优点

1.节省内存,运算速度快
通常的for…in…循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件。它可以是list = [1, 2, 3]等。 但它的缺陷是所有数据都在内存中,如果有海量数据的话将会非常耗内存。
而生成器(generator)是可以迭代的,但只可以读取它一次。因为用的时候才生成。比如 range(3),注意这里用到了range(),它就不是数组,只有每次用到才调用,而上面的例子是[]。

简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。
带有yield的函数不仅仅只用于for循环中,而且可用于某个函数的参数,只要这个函数的参数允许迭代参数。比如array.extend函数,它的原型是array.extend(iterable)。

代码示例

def yield_test1(n):  
    while n>0:           
        yield n   
        n=n-1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
a = yield_test1(4)
print(next(a))
print(next(a))
print(next(a))
print(next(a))
#尝试在多加一个print(next(a)),则会报错。因为无法满足迭代条件。
Output:
4
3
2
1

总结

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。

参考文章

Python yield使用浅析
彻底理解python中的yield

标签:函数,generator,Python,生成器,yield,next,迭代
来源: https://blog.csdn.net/qq_44554428/article/details/120604796

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有