python 生成器
一、生成器函数
1.yield关键字
定义:含义yield关键字的函数,是生成器函数
作用:返回值,不终止函数,若yield后无值,则返回None
用法:与return关键字不能共存,必须在函数内部
2.调用函数
调用生成器函数返回的是生成器
3.常用方法
1)__next__()
格式:生成器.__next__()
作用:执行生成器函数内部代码,遇到yeild关键字停止,并返回值,若没有yield作为结尾,会报错
# 生成器函数 def generator(): print(1) yield 'a' print(2) yield 'c' g = generator() # g是生成器 print(g) ret = g.__next__() # 执行生成器函数内部代码直到遇到yield print(ret)
2)for循环
作用:执行生成器内部代码,结尾不是yield关键字,不会报错
# 生成器函数 def generator(): print(1) yield 'a' print(2) yield 'c' g = generator() # g是生成器 for i in g: print(i)
3)send()
格式:send(传递的数据)
作用:执行下面的代码,给上一个yield位置传递数据
注意:不能在初始使用send()方法
def generator(): print(1) count = yield 'a' print(count) print(2) yield 'c' g = generator() # g是生成器 ret1 = g.__next__() print('>>>{}'.format(ret1)) # str格式输出 format # g.__next__() ret2 = g.send('a123') print('***%s' % ret2) # 格式化输出
# 预激协程,求平均值 def init(func): def inner(*args, **kwargs): g = func(*args, **kwargs) next(g) # g.__next__() 一样 return g return inner @init def average(): total = 0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/count av = average() av1 = av.send(10) av2 = av.send(20) av3 = av.send(30) print(av3)
4)yield from
作用:简化代码
格式:yield from 可迭代对象
def generator(): # for i in range(10): # yield i yield from range(10) # 和for循环的作用一样 g = generator() for i in g: print(i)
二、生成器表达式
1.格式:生成器 = (为True操作 for i in 可迭代对象 if 条件)
2.分类
遍历
筛选
# 遍历,1-10 g = (i for i in range(1, 11)) for i in g: print(i)
# 筛选 g = (i**2 for i in range(10) if i > 5) for i in g: print(i)
三、推导式
1.列表推导式
# 遍历,1-10 li1 = [i for i in range(1, 11)] print(li1) # 筛选 li2 = [i**2 for i in range(10) if i > 5] print(li2)
列表推导式和生成器表达式的区别:
1)格式:列表推导式[],生成器表达式()
2)内存消耗:生成器表达式消耗内存少
2.字典推导式
# 把value值变成大写 dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} dic1 = {k: dic[k].upper() for k in dic} print(dic1) # 筛选 dic2 = {k: dic[k] for k in dic if dic[k] == 'v3'} print(dic2)
3.集合推导式
# 遍历 set1 = {-1, 1, -2, 2} set2 = {i**2 for i in set1} # 集合,去重 print(set2) # 筛选 set3 = {i*i for i in set1 if i == 2} print(set3)
四、总结
1.生成器的本质是迭代器
2.yield关键字
作用:返回值
3.调用生成器函数获得的值是生成器
4.生成器函数的方法:
__next__(),执行生成器函数内部代码,直到遇到yield
for循环
send(),取值,传递数据给上一个yield位置
yield from,可迭代,返回值,不是整体
5.生成器表达式,获取的是生成器
6.生成器取值,next方法,for循环,数据类型的强转(生成器->list),send
7.一个生成器里的值,只能取一次,而且不找它要的时候,它是不会取的
def demo(): for i in range(4): yield i g = demo() g1 = (i for i in g) g2 = (i for i in g1) print(list(g1)) print(list(g2))