1、定义
通过列表生成式(列表推导式),我们可以直接创建一个列表,但是,受到内存的限制,列表容量是有限的,而且,创建一个包含100万元素的列表,不仅占用很大的内存空间。如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?那样就不必创建完整的list,从而节省大量的空间,在python中,这种一边循环一边计算的机制,称为生成器:generator
2、得到生成器方式
-
通过列表推导式得到生成器
#列表推导式 newlist = [x*3 for x in range(20)] print(newlist) #得到生成器 new_generator = (x*3 for x in range(20)) print(type(new_generator))
-
借助函数完成。只要出现了yield关键字的话,这个函数就不是函数了,叫生成器!其中yield关键字具有(return + 暂停)的功能!
def func(): n = 0 while True: n += 1 yield n # 等效于:return + 暂停 g = func()
注: 当生成器中不能生成元素时,则会显示报错信息:StopIteration
3、通过生成器获取元素
-
通过内置函数__next__()
#生产产品的一种方式,内置函数 print(new_generator.__next__()) # 0 print(new_generator.__next__()) # 3 print(new_generator.__next__()) # 6
-
通过系统函数next()
#生产产品的另一种方式,系统函数 print(next(new_generator)) # 9 print(next(new_generator)) # 12 print(next(new_generator)) # 15
4、实例:斐波那契数列
步骤:
1、定义一个函数,函数使用yield关键字
2、调用函数,接受调用的结果
3、得到结果就是生成器
4、借助于next() 或 __next__得到生成器中的元素
#斐波那契数列
def fib(length):
a,b = 0,1
n = 0
while n<length:
#全是b元素的生成器
yield b #return b+暂停
a,b = b,a+b
n += 1
return '没有更多元素!!!' #生成器没有元素后,报错则会显示return后的返回信息!
g = fib(5)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
5、send()内置函数
send(value):向每次生成器调用中传值,第一调用必须传值None!
def gen():
i = 0
while i<5:
temp = yield i #return + 暂停
print('temp:',temp)
i += 1
return '没有更多的数据'
g = gen()
print(g.send(None))
n1 = g.send('呵呵')
print('n1:',n1)
n2 = g.send('哈哈')
print('n2:',n2)
6、生成器应用–>协程(多任务)
#协程,交替完成(多应用)
def task1(n):
for i in range(n):
print('正在搬第{}砖!'.format(i))
yield None #只使用了yield的暂停功能
def task2(n):
for i in range(n):
print('正在听第{}首歌'.format(i))
yield None #只使用了yield的暂停功能
g1 = task1(5)
g2 = task2(5)
while True:
try:
g1.__next__()
g2.__next__()
except:
pass
7、总结
生成器:generator
定义生成器方式:
-
通过列表推导式方式
g = (x+1 for x in range(6)) -
函数+yield
def func():
…
yield
g = func()扫描二维码关注公众号,回复: 10532751 查看本文章
产生元素:
1.next(generator) -->每次调用都会产生一个新的元素,如果元素产生完毕,再次调用的话就会产生异常
2.生成器自己的方法:
g.__next__()
g.send(value)
应用:协程