week4-python之生成器
生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
生成器就是迭代器
yield的功能:
1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
2 函数暂停与再继续运行的状态是由yield决定
def func():
print('first')
yield 11111111
print('second')
yield 2222222
print('third')
yield 33333333
print('fourth')
g=func()
print(g)
from collections import Iterator
print(isinstance(g,Iterator))
print(next(g))
print('======>')
print(next(g))
print('======>')
print(next(g))
print('======>')
for i in g: #i=iter(g)
print(i)
无限大打印不会卡,因为内存同时只存在一个值
def func(n):
print('开始打印')
while True:
yield n
n+=1
g=func(0)
# print(next(g))
# print(next(g))
# print(next(g))
for i in g:
print(i)
定义一个range函数,使用raise 捕获StopIteration异常,for循环原理遇到StopIteration异常会自动结束循环:
def my_range(start,stop):
while True:
if start == stop:
raise StopIteration
yield start #2
start+=1 #3
g=my_range(1,3)
for i in my_range(1,3):
print(i)
yield与return的比较
1.相同:都有返回值的功能
2.不同:return只能返回一次值,而yield可以返回多次值
模拟linux tail -f 加管道过滤错误关键(grep)
# python3 tail.py -f access.log | grep 'error'
import time
def tail(filepath):
with open(filepath, 'r') as f:
f.seek(0, 2)
while True:
line = f.readline()
if line:
yield line
else:
time.sleep(0.2)
def grep(pattern,lines):
for line in lines:
if pattern in line:
print(line,end='')
grep('error',tail('access.log'))
生产器表达式:
g=('egg%s' %i for i in range(1000))
print(g)
print(next(g))
print(next(g))
print(next(g))
with open('a.txt',encoding='utf-8') as f:
# res=max((len(line) for line in f))
res=max(len(line) for line in f)
print(res)
print(max([1,2,3,4,5,6]))
with open('a.txt',encoding='utf-8') as f:
g=(len(line) for line in f)
print(max(g))
print(max(g))
print(max(g))
应用:
res=sum(i for i in range(3))
print(res)
with open('db.txt',encoding='utf-8') as f:
l=(float(line.split()[1])*int(line.split()[2]) for line in f)
print(sum(l))
l=[]
for line in f:
goods=line.split()
price=float(goods[1])
count=int(goods[2])
cost=price * count
l.append(cost)
print(sum(l)) #196060.0
with open('db.txt',encoding='utf-8') as f:
info=[{'name':line.split()[0],
'price':float(line.split()[1]),
'count':int(line.split()[2])} for line in f if float(line.split()[1]) >= 30000]
print(info)
志不强者智不达
浙公网安备 33010602011771号