生成器和表达式
1. 生成器
生成器的本质就是迭代器
生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).
生成器一般由生成器函数或者生成器表达式来创建
其实就是手写的迭代器
2. 生成器函数
和普通函数没有区别. 里面有yield的函数就是生成器函数.
函数中如果有yield 这个函数就是生成器函数. 生成器函数+() 获取的是生成器. 这个时候不执行函数
yield: 相当于return 可以返回数据. 但是yield不会彻底中断函数. 分段执行函数.
gen.__next__() 执行函数. 执行到下一个yield.
gen.__next__() 继续执行函数到下一个yield.
def func(): #这个函数就是一个生成器函数,因为有yield
print("娃哈哈")
yield 1 # return和yield都可以返回数据
gen = func() # 不会执行你的函数. 拿到的是生成器
print(gen.__next__()) #先打印"娃哈哈",然后返回1,打印1
生成器函数在执行的时候. 默认不会执行函数体. 返回生成器
通过生成器的__next__()分段执行这个函数.
def order():
for i in range(10000):
yield "衣服"+str(i)
g = order() # 获取生成器
amber= g.__next__()
print(amber) #衣服0
icy= g.__next__()
print(icy) #衣服1
send() 和__next__()是一样的. 可以执行到下一个yield, 可以给上一个yield位置传值
def eat():
print("我吃什么啊")
a = yield "馒头"
print("a=",a)
b = yield "鸡蛋灌饼"
print("b=",b)
c = yield "韭菜盒子"
print("c=",c)
yield "GAME OVER"
gen = eat() # 获取生成器
ret1 = gen. __next__()
print(ret1) # 我吃什么啊? 馒头
ret2 = gen.send("胡辣汤") #a=胡辣汤
print(ret2) #鸡蛋灌饼
ret3 = gen.send("狗粮") #b=狗粮
print(ret3) #韭菜盒子
ret4 = gen.send( "猫粮") #c=猫粮
print(ret4) #game voer
send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用send(),结尾只能用yield,否则会报错
def func():
yield 1
yield 3
yield 5
yield 7
yield 9
for i in func(): # for的内部一定有__next__()
print(i) #1,3,5,7,9
print(list(func())) # 内部都有__next__() #1,3,5,7,9
3. 推导式
用一句话来生成一个列表
lst = ["python"+str(j) for j in range(1,16)] print(lst)
1. 列表推导式 [结果 for循环 条件筛选]
# 100以内能被3整除的数的平方 lst = [i*i for i in range(100) if i%3==0] print(lst)
2. 字典推导式 {k:v for循环 条件筛选}
# [11,22,33,44] => {0:11,1:22,2:33}
lst = [11,22,33,44]
dic = {i:lst[i] for i in range(len(lst)) if i < 2} # 字典推导式就一行
print(dic)
3. 集合推导式 {k for循环 条件}
lst = [1, 1, 4, 6,7,4,2,2]
s = { el for el in lst } #可去重
print(s)
4. 生成器表达式
tu = (i for i in range(10)) # 没有元组推导式(因为元祖不能增加),这是生成器表达式
print(tu) # 生成器 print(tu.__next__()) #0 print(tu.__next__()) #1 print(tu.__next__()) #2 print(tu.__next__()) #3 print(tu.__next__()) #4 print(tu.__next__()) #5
(结果 for循环 条件)
特点:
1. 惰性机制 #没有__next__()就不会取值
2. 只能向前
3. 节省内存(鸡蛋)
def func():
print(111)
yield 222
yield 333
g = func() # 获取生成器
g1 = (i for i in g) # 生成器
g3 = func()
g2 = (i for i in g3) # 生成器
print(list(g)) # [222,333] 源头. 从源头把数据拿走了
print(list(g1)) # [] 这里执行的时候. 源头已经没有数
print(list(g2)) #[222,333],这个是新的g3生成器.

浙公网安备 33010602011771号