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)
posted @ 2017-07-25 07:37  warren1236  阅读(90)  评论(0)    收藏  举报