python 生成器
推导式
通过列表生成式(列表推导式),我们可以直接创建一个列表
但是受到内存限制,列表容量是有限的
而且创建一个100万元素的列表,会占用很大的存储空
如果我们只需要访问前面几个元素,那后面大多数元素占用的空间就白白浪费了
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量空间,在python中,这样一边循环一遍计算的机制,称为生成器,generator
#这是列表推导式
list=[x*3 for x in range(20)]
print (type(list))
#生成器把[]改成 ()就成了生成器,所以()是生成器,[]是列表推导式,{}是字典推导式
list1=(x*3 for x in range(20))
print (type(list1))
print (list1)
#推到式是一股脑的生成一列数据,而生成器可以根据你的动作得到你想要的数据
#成了生成器后,会有特定的函数,比如__next__,每次调用可以得到列表的下一个元素。这样只有调用才会占用内存,用到什么就调用什么,可以减少使用内存
#方式一
print (list1.__next__())
print (list1.__next__())
print (list1.__next__())
#方式二,使用next内置函数,next里面是生成器对象,每调用一个next就会产生一个元素,这里输出9
#当生成器next一直调用,range(10),超出10的时候再次调用会报错 StopIteration
print (next(list1))
示例
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# BY:wenchao.Li time: 2021/10/11
'''
条件:
1.定义一个函数,函数中有yield
2。调用函数,接收调用的结果
3.得到的结果就是生成器,
4.借助 __next__ 或者 next 得到元素
'''
def func():
n=0
while True:
n+=1
#下面不加yield,加一个print (n)就是一个死循环了,加上yeild就是一个生成器
# print (n)
#注意,只要函数中出现 yield就是生成器了,不是一个函数了
yield n
g=func()
print (g)
#这里会输出1,2,从这里可以看出, yield相当于 return功能+ 暂停的效果,不会一直死循环。并输入结果
print (next(g))
print (next(g))
#在这里使用生成器计算斐波那契函数,
#菲波那切函数是从 0开始, 第三个数是第一个和第二个数相加。 第四个是第三个和第二个相加,以此类推
def fib(length):
a,b=0,1
n=0
while n < length:
yield b
a,b=b,a+b
n+=1
return '没有更多的参数了'
result=next(fib(3))
print("斐波那契的第三个数是:{}".format(result))
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# BY:wenchao.Li time: 2021/10/11
def gen():
i=0
while i < 5:
temp = yield i
print ('temp',temp)
i +=1
return "没有更多的数据"
g=gen()
print (next(g))
print (next(g))
print (next(g))
#可以看到上面输出的是None,除了next和__next__还有send
print (g.send(None))
n1=g.send("嘻嘻")
print ('n1',n1)
n2=g.send("哈哈")
print ('n2',n2)