目录
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)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# BY:wenchao.Li time: 2021/10/11
#进程》线程》协程
#迅雷的协程底层就是拿生成器来写的
#一个100G电影,10个线程同时工作,分成10分,同时进行
#生成器多任务
def task1(n):
for i in range(n):
print ("正在搬第{}几块砖".format(i))
def task2(n):
for i in range(n):
print ("正在听第{}首歌".format(i))
#这样只能先搬完10块砖,才能听10首歌。那怎么才能并行呢,这时候生成器就可以了
task1(10)
task2(10)
####################################################################################分割线,下面的是加了生成器并行部分
def task1(n):
for i in range(n):
print ("正在搬第{}几块砖".format(i))
yield None
def task2(n):
for i in range(n):
print ("正在听第{}首歌".format(i))
yield None
#有了生成器,顺序就可以由自己决定了
g1=task1(5)
g2=task2(5)
while True:
try:
g1.__next__()
g2.__next__()
except:
pass
###########上面可以控制打印任务交替了,但是并没有并发,接下来会涉及到协程的,后面会再讲,这里暂且停止了
#回顾知识点:
'''
生成器方式:
1.通过列表推导式子
g=(x*3 for x in range(10))
2.函数列有 yield
产生元素:
1.next(generactor) 每次调用产生一个元素,元素产生完毕,再次调用就会异常
2.生成器自己的办法:
g.__next__
g.send(key)
标签:__,10,python,生成器,yield,next,print
From: https://www.cnblogs.com/liwenchao1995/p/17551794.html