13、生成器
13.1 创建生成器
简易生成器:
list1 = [x for x in range(5)]
print(list1)
obj1 = (x for x in range(5)) #简易生成器
print(obj1)
展示:
[0, 1, 2, 3, 4]
<generator object <genexpr> at 0x0000026142D51318>
函数生成器:
def fei(num):
a = 0
b = 1
current_index = 0
while current_index < num:
# print(a)
yield a
a,b = b,a+b
current_index += 1
gen = fei(4)
print(gen)
for i in gen:
print(i)
# ret = next(gen)
# print(ret)
# ret = next(gen)
# print(ret)
# ret = next(gen)
# print(ret)
# ret = next(gen)
# print(ret)
展示:
<generator object fei at 0x0000024E097E2318>
0
1
1
2
注意点:
函数里面出现yield,说明已经不是一个简单的函数,而是生成器,用for遍历(或者next少用)
13.2 关于生成器
from collections.abc import Iterable
list1 = [x for x in range(5)]
print(list1)
obj1 = (x for x in range(5))
# print(tuple(obj1))
print(obj1)
print(isinstance(obj1,Iterable))
展示:
[0, 1, 2, 3, 4]
<generator object <genexpr> at 0x0000026142D51318>
True
注意点:
1、(推导式)生成的是一个生成器
2、如果想要转元组,tuple进行强转
3、isinstance判断,生成器是一个可迭代对象,用for循环可以挨个取出每一个对象
13.3 关于生成器的访问
方法一:
print(next(obj1))
print(next(obj1))
print(next(obj1))
print(next(obj1))
print(next(obj1))
print(next(obj1,'没有数据了'))
# for i in obj1:
# print(i)
展示:
0
1
2
3
4
没有数据了
注意点:
1、访问方式:(1)通过for循环来进行遍历
(2)next()如果遍历的次数超过总个数,会报错,所以使用的时候,要么赋值默认值,要么使 用try
方法二:
def fei(num):
a = 0
b = 1
current_index = 0
while current_index < num:
params = yield a
print('本次接受的参数',params)
a,b = b,a+b
current_index += 1
# 产生一个生成器对象
gen = fei(5)
# gen.send(None)
print(next(gen))
print('##########')
print(gen.send('java'))
print('$$$$$$$$$$$$')
print(gen.send('python'))
print('%%%%%%%%')
print(gen.send('go'))
展示:
0
##########
本次接受的参数 java
1
$$$$$$$$$$$$
本次接受的参数 python
1
%%%%%%%%
本次接受的参数 go
2
注意点:
如果使用send函数唤醒生成器,第一次调用send的时候,传入的值为None
一般情况下,会使用next来唤醒执行第一次
13.4 yield与return的区别
yield在生成器中的作用:
[外链图片转存失败(img-iPD3eqYP-1564742124133)(G:\CSDN1\基础知识\基础知识1.png)]
yield与return的区别
yield的特点:
程序在执行的时候遇到yield会暂停执行,如果yield后面有返回值,先把值返回再暂停
再次启动生成器获取数据的时候会从暂停的地方开始执行
Return只返回一次值,后面有代码不执行,yield可以多次返回值