三、生成器
生成器
利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。生成器是一类特殊的迭代器。
2.1 创建生成器的方法1
要创建一个生成器,有很多种方法,第一种方法很简单,只要把一个列表推导式的[]改成()
列表推导式:
l = [i for i in range(1,10) if i % 2 == 0]
生成器:
l = (i for i in range(1,10) if i % 2 == 0)
#生成器是一类特殊的迭代器,所以也可以使用next()函数或者__next__()方法来获取生成器的值
print(next(l)) #2
print(l.__next__()) #4
print(next(l)) #6
print(l.__next__()) #8
#也可以使用for...in来循环该生成器
for i in l:
print(i,end = ' ')
#2 4 6 8
2.2 创建生成器的方法2
要求:
-
函数中包含 yield语句
- yield 可以去阻断当前函数的执行,当使用next()函数,或者使用
__next__()方法都会让这个函数继续执行,当执行到下一个 yield语句的时候,又会被暂停 - 一直到生成器内所有的yield语句都被执行后,再次使用next()函数,或者使用
__next__()方法都会让这个函数继续执行时,将后续代码执行完后,会弹出StopIteration异常
- yield 可以去阻断当前函数的执行,当使用next()函数,或者使用
-
直接输出这个函数的结果就是'生成器'<generator object test at 0x03CFBBC0>
yield关键字可以不指定值
def test():
print('x')
yield 1
print('a')
yield 2
print('b')
yield 3
print('c')
yield 4
print('d')
a = test() #该函数并未被执行,仅仅用于产生一个生成器
print(next(a))
'''
x
1
yield 可以去阻断当前函数的执行,当使用next()函数,或者使用`__next__()`方法都会让这个函数继续执行,当执行到下一个 yield语句的时候,又会被暂停
'''
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
'''
x
1
a
2
b
3
c
4
d
StopIteration
'''
2.2.1 send()
- send()方法有一个参数,指定的是上一次被挂起的yield语句的返回值
- 相比于
__next__()方法,send可以额外的给yield语句传值 - 注意第一次调用
变量名.send(None)
def zzw():
res1 = yield 1
print(res1)
res2 = yield 2
print(res2)
a = zzw()
print(next(a))
print(a.send('zhang'))
#此刻 send 既有继续执行函数的功能,还有着将实参作为上一次yield语句的值传递给变量res1的作用
print(a.send('zhang'))
#TypeError: can't send non-None value to a just-started generator
#如果将send作为启动函数来代替next(),那么就不能加入参数,否则会报错。因为不存在上一次yield语句
print(a.send(None))
print(a.send(None))
#send默认参数值为None,即如果使用send方法不填入实参,那么输出结果会报错
print(a.send())
#TypeError: generator.send() takes exactly one argument (0 given)

浙公网安备 33010602011771号