可以理解为一种数据类型。这种数据类型自动实现了迭代器协议,所以生成器是可迭代类型。(像列表这种,需要调动自身的__iter__方法才形成可迭代器)。所以在生成器中,可以自动在后面写一个.next,因为这是可迭代对象共有的特点。
(1)函数
使用yield而不是通过return返回。这样的话一执行,得到的就是生成器。(生成器的本质,就是一个数据类型)
def test(): yield 1 yield 2 #yield和return的区别是:1.得到一个生成器类型 2.可以进行多次返回 yield 3 g=test() print(g) #输出结果:<generator object test at 0x0000028AA963C740> print(g.__next__()) print(g.__next__()) #生成器自带next功能,会自动输出
def test(): yield 1 yield 2 yield 3 yield 4 print(test()) #输出结果为<generator object test at 0x0000022805F4C740>,也是生成了一个迭代器
(2)生成器表达式
补充:三元表达式/三元运算
name="alex" "SB" if name=="alex" else "帅b" #这就是三元表达式。含义:如果判断条件成立,返回SB,不成立返回帅B
res="SB" if name=="alex" else "帅b"
print(res) #输出结果SB
补充:通过三元计算完成列表解析,生成一个列表
方法一:不用三元计算,通过for循环写一个列表
list_egg=[] for i in range(10): list_egg.append("鸡蛋%s" %i) print(list_egg)
#输出结果:[‘鸡蛋0‘, ‘鸡蛋1‘, ‘鸡蛋2‘, ‘鸡蛋3‘, ‘鸡蛋4‘, ‘鸡蛋5‘, ‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]
方法2:通过三元计算 解析列表
l=["鸡蛋%s" %i for i in range(10)] print(l)
#输出结果:[‘鸡蛋0‘, ‘鸡蛋1‘, ‘鸡蛋2‘, ‘鸡蛋3‘, ‘鸡蛋4‘, ‘鸡蛋5‘, ‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]
li=["鸡蛋%s" %i for i in range(10) if i >5]
print(li)
#输出结果:[‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]
li=["鸡蛋%s" %i for i in range(10) if i >5 else i] #这样就会报错,因为只能有三元
但是!!通过三元计算生成的是一个列表,这样会占据大量内存,如果数据过大时,会导致电脑卡死。
那该怎么办呢?
答案来啦:通过生成器的方法,弄出一个迭代器出来,然后想产生的时候,一个一个__next__就行
laomuji=("鸡蛋%s" %i for i in range(10)) #注意这里,和三元计算生成列表的写法类似,只不过中括号改成了小括号 print(laomuji) #输出结果<generator object <genexpr> at 0x000001FDCE14C740> print(laomuji.__next__()) #输出结果:鸡蛋0
print(next(laomuji)) #这种写法也可以,输出结果:鸡蛋1
??????????这种就是生成器
生成器表达式的应用:
sum函数
如果写一个很大的列表,然后对他进行求和,会占用很大的内存空间
因此我们采取一种生成器的方式,代码如下
a=sum(i for i in range(100)) #后面的操作就是生成了一个迭代器,然后用sum内置的东西,对这个迭代器进行for循环
print(a)
原文:https://www.cnblogs.com/yxzymz/p/12751397.html