python生成器yield函数和表达式

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
yieldyield'阅'
>>> next(y)
None
yieldyield'线'
>>> y.send('t')
t
yieldyield'条'
>>> 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)
('梯梯', '阅阅')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值