暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

python生成器yield函数和表达式

原创 梯阅线条 2023-10-06
164

1 python生成器yield函数和表达式

python生成器包括生成器函数和生成器表达式。

NO 生成器 描述
1 生成器函数 函数主体包含yield语句的函数,返回生成器对象,每次调用__next__(),执行到yield语句返回一个结果并停止执行后面的语句,再次调用从返回结果后面语句继续执行直到yield语句返回结果。
2 生成器表达式 圆括号编写的列表解析,返回生成器对象,每次调用__next__(),获取下一项生成器内容。通过list()和tuple()转为对应容器。

python生成器节省内存空间,因为返回生成器对象,而不是一次生成全部数据。

python生成器用于可以通过某种算法推算得到多个数据,不需一次生成全部数据,而是按需产生数据的场景。

1.1 python生成器函数yield

用法

def 函数名([入参]): ... yield 表达式 ...

描述

NO 要点 描述
1 组成 python生成器函数是包含yield语句的函数。yield语句编译为生成器。
2 返回 调用生成器函数返回生成器对象,因为包含__next__()方法,所以是迭代器对象,支持迭代协议,可用于迭代环境。
3 执行 调用__next__()方法执行函数主体,运行到yield语句返回表达式结果,并且挂起函数不再执行后面语句;再次调用__next__()方法,回到yield语句,继续执行后面语句,再次运行到yiled语句返回结果,并且挂起函数;依次循环调用__next__()方法,直到最后一项完成,引发StopIteration异常。

示例

>>> def yieldF(): print('for开始前只执行一次') for c in '梯阅线条': print('yield前') yield c print('yield后') print('for结束后只执行一次') >>> y=yieldF() >>> type(y) <class 'generator'> >>> '__next__' in dir(y) True >>> t=y.__next__() for开始前只执行一次 yield前 #执行到yield语句,返回表达式结果,停止执行退出函数 >>> t #返回表达式结果 '梯' >>> t=y.__next__() #再次调用__next__,从yield后面一条语句开始执行, yield后 #继续for循环,直到yield语句,返回表达式结果,停止执行退出函数 yield前 >>> t '阅' >>> t=y.__next__() yieldyield前 >>> t '线' >>> t=y.__next__() yieldyield前 >>> t '条' >>> t=y.__next__() yield后 #for循环结束 for结束后只执行一次 #捕获到异常yield结束 Traceback (most recent call last): File "<pyshell#47>", line 1, in <module> t=y.__next__() StopIteration

1.2 isgeneratorfunction()

描述

python函数isgeneratorfunction(函数名)用于判断一个函数是否为生成器函数。

示例

>>> def isgf(n): for i in range(n): yield i >>> list(isgf(3)) [0, 1, 2] >>> from inspect import isgeneratorfunction as isg >>> isg(isgf) True >>> isg(isgf(3)) False

1.3 python存储yield值

描述

python通过list()或tuple()函数,将生成器函数yield表达式的值存储为列表或元组。

示例

>>> def yieldF(): print('for开始前只执行一次') for c in '梯阅线条': print('yield前') yield c print('yield后') print('for结束后只执行一次') >>> yl=list(y) for开始前只执行一次 yieldyieldyieldyieldyieldyieldyieldyieldfor结束后只执行一次 >>> yl ['梯', '阅', '线', '条']

1.4 python遍历yield项

描述

python的yield函数生成迭代器对象,支持迭代环境,比如通过for循环遍历yield迭代项。

示例

>>> def yieldF(): print('for开始前只执行一次') for c in '梯阅线条': print('yield前') yield c print('yield后') print('for结束后只执行一次') >>> y=yieldF() >>> y=yieldF() >>> for c in y: print('c前') print(c) print('c后') #for循环是迭代工具,会自动调用迭代对象的__next__()方法 #c为每次调用__next__()方法的yield返回表达式结果 #for循环自动调用__next__()方法,执行函数体, #遇到yield,将表达式结果存储到c for开始前只执行一次 yield前 c前 梯 c后 yieldyield前 c前 阅 c后 yieldyield前 c前 线 c后 yieldyield前 c前 条 c后 yieldfor结束后只执行一次

1.5 python生成器的next方法

描述

python生成器g.next()方法,等效于next(g)。

调用next方法时,开始执行函数体,到yield语句暂停执行,返回表达式结果,再次调用next方法,从yield后面语句继续执行,直到yield语句或者遇到StopIteration异常停止。

示例

>>> def yieldF(): print('for开始前只执行一次') for c in '梯阅线条': print('yield前') yield c print('yield后') print('for结束后只执行一次') >>> y=yieldF() >>> y.__next__() for开始前只执行一次 yield'梯' >>> next(y) yieldyield'阅' >>> next(y) yieldyield'线' >>> next(y) yieldyield'条' >>> next(y) yieldfor结束后只执行一次 Traceback (most recent call last): File "<pyshell#25>", line 1, in <module> next(y) StopIteration

1.6 python生成器的send方法

用法

g.send(arg)

描述

python生成器对象的send()方法,和__next__()方法类似,可以返回下一个yield结果并暂停再继续。同时,send(arg)可以将arg发送给yield后面的变量。

(1) 第1次调用,用send(None),或__next__()方法。

第1次不送None,会报下面的错误,执行函数体时未设置变量接收入参。

TypeError**😗* can’t send non-None value to a just-started generator

(2) send(arg),返回yield结果,并将arg发送给yield后面的变量。

(3) 根据arg值停止生成器或做其他处理。

示例

>>> def yieldF(): for c in '梯阅线条': print('yield前') x=yield c print(x) print('yield后') >>> y=yieldF() >>> y.send('t') Traceback (most recent call last): File "<pyshell#44>", line 1, in <module> y.send('t') TypeError: can't send non-None value to a just-started generator >>> y.send(None) yield前 '' >>> y.send('y') y yield后 yield前 '' >>> next(y) None yield后 yield前 '线' >>> y.send('t') t yield后 yield前 '' >>> y.send('t') t yield后 Traceback (most recent call last): File "<pyshell#49>", line 1, in <module> y.send('t') StopIteration

1.7 python用yield生成斐波那契数列

描述

斐波那契数列是递归数列,第1和第2个数为1,第3个数开始,每一项都等于前两项之和。本示例通过yield生成斐那契数列。

示例

>>> def fib(max): n,a,b=0,0,1 while n<max: yield b a,b=b,a+b n=n+1 >>> list(fib(10)) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1.8 python生成器表达式

用法

(变量表达式 for 变量 in 迭代对象)

描述

python的生成器表达式放在圆括号内,返回一个生成器对象,每次调用next方法,返回表达式结果。

示例

>>> gexp=(x*2 for x in range(10) if x%2==1) >>> next(gexp) 2 >>> next(gexp) 6 >>> next(gexp) 10 >>> next(gexp) 14 >>> next(gexp) 18 >>> next(gexp) Traceback (most recent call last): File "<pyshell#43>", line 1, in <module> next(gexp) StopIteration #生成器的括号可以省略 >>> sum(x*2 for x in range(10) if x%2==1) 50 >>> sum((x*2 for x in range(10) if x%2==1)) 50 >>> sorted(x*2 for x in range(10) if x%2==1) [2, 6, 10, 14, 18] #生成器的括号不可省略 >>> sorted((x*2 for x in range(10) if x%2==1),reverse=True) [18, 14, 10, 6, 2]

1.9 python生成器为单迭代对象

描述

如果iter()返回迭代器为对象本身,则为一次迭代器。

python生成器函数和生成器表达式为一次迭代器,即单迭代对象。

多个迭代器会执行同一迭代器结果,任何迭代器完成,所有迭代器都完成。

必须重新生成迭代器进行使用。

示例

>>> g=(x*2 for x in '梯阅线条') >>> iter(g) is g True >>> g1,g2=iter(g),iter(g) >>> next(g1),next(g2) ('梯梯', '阅阅') >>> next(g1),next(g2) ('线线', '条条') >>> next(g1) Traceback (most recent call last): File "<pyshell#62>", line 1, in <module> next(g1) StopIteration #多个迭代器会执行同一迭代器结果,任何迭代器完成,所有迭代器都完成。 >>> next(g2) Traceback (most recent call last): File "<pyshell#63>", line 1, in <module> next(g2) StopIteration #必须重新生成迭代器进行使用。 >>> g=(x*2 for x in '梯阅线条') >>> g1,g2=iter(g),iter(g) >>> next(g1),next(g2) ('梯梯', '阅阅')

2 END

本文首发微信公众号:梯阅线条

更多内容参考python知识分享或软件测试开发目录。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论