一.什么是生成器
- 在python中,使用yeid的函数被称为生成器。
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
二.生成器和yeild
def foo(start,stop,step=1):
print('start ....')
while start < stop:
yield start
start+=step
print('end...')
g=foo(0,3)
print(g)
print(g.__iter__)
print(g.__next__)
print(next(g))
print(next(g))
print(next(g))
print(next(g)) # 最后一个yield执行完,报错
三.yield表达式应用
def eater():
print('ready to eat')
while True:
food=yield
print('get the food {},and start to eat'.format(food))
a=eater() # 得到生成器对象
print(a)
next(a) # 执行到yield挂起
a.send('baozi')
print(a.send('apple'))
a.send(None)
next(a)
# 针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用g.send()方法为函数体传值,g.send(None)等同于next(g)
# 加上装饰器版本
初始化所有生成器函数的装饰器
def init(func):
def warpper(*args,**kwargs):
print('hello')
g=func(*args,**kwargs)
next(g)
return g
return warpper
@init
def eater():
print('ready to eat')
while True:
food=yield
print('get the food {},and start to eat'.format(food))
# 加上装饰器后eater=init(eater)=warpper
eater()=warpper()=g
a=eater() # 直接完成出事化next操作
a.send('apple')
def eater():
print('ready to eat')
food_list=[]
while True:
food=yield food_list
food_list.append(food)
g=eater() # 拿到生成器
print(next(g)) # 初始化
print(g.send('apple'))
print(g.send('banana'))
四.三元表达式
- 语法
res = 条件成立时返回的值 if 条件 else 条件不成立时返回的值
4.1举例
# 普通写法
def max(x,y):
if x>y:
return x
else:
return y
res=max(1,2)
print(res)
# 用三元表达式
x=1
y=2
res=x if x>y else y
print(res)
4.2列表生成式
list=[]
for i in range(10):
list.append('xixi {}'.format(i))
print(list)
xixi=['xixi {}'.format(i) for i in range(10)]
print(xixi)
4.3生成器表达式
list=[x*x for x in range(3)]
print(list) # 列表表达式返回一个列表
g=(x*x for x in range(3))
print(g)
print(next(g))
print(next(g))
print(next(g))
# 对比列表生成式,生成器表达式的优点自然是节省内存(一次只产生一个值在内存中)
读取大文件字节数,基于生成器表达式完成
with open('C:/Users/魏旭/PycharmProjects/test/haha','rb') as f:
nums=(len(line) for line in f)
total=sum(nums)
print(total)