五、Python之迭代器与生成器

1. 迭代器

迭代:指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值
对于序列类型:str,list,tuple可以依赖索引迭代取值;但对于dict,set,文件等,python必须提供一种不依赖索引的迭代取值的方法
可迭代对象 obj.iter () # str,list,tuple,dict,set,文件
迭代器对象 obj.iter (),obj.next () # 文件

d = {'name':'ee','age':18,'sex':'male'}
d_iter = d.__iter__()       #等同于 d_iter = iter(d)
print(d_iter.__next__())    #name   #等同于 print(next(d_iter))
print(d_iter.__next__())    #age
print(d_iter.__next__())    #sex
print(d_iter.__next__())    #StopIteration 报异常说明已经迭代完了

#result
name
age
sex
Traceback (most recent call last):
    File "E:/Python/OldBoy/20issue/d4/bolog.py", line 6, in <module>
StopIteration

总结:
        可迭代对象不一定是迭代器对象
        迭代器对象一定是可迭代的对象
        可调用 obj.__iter__()方法,得到的是迭代器对象,而对于迭代器对象调用obj.__iter__()得到的仍然是它本身

2. 生成器

生成器:只要在函数内部出现yield关键字,那么再执行函数时就不会执行函数代码,会得到一个结果,该结果就是生成器
生成器本身就是迭代器

def func():
    print('====>1')
    yield 1
    print('====>2')
    yield 2
    print('====>3')
    yield 3
g= func()   #g.__iter__() g.__next__():g现在就是一个迭代器
print(next(g))

#result
====>1
1

3.协程函数之yield表达式

yield 功能:
1.提供了一种自定义迭代器对象的方法
2.yield与return相似,但yield可以返回多次值,函数的暂停和执行由yield来控制;而return只返回一次值,且返回之后就结束了

def eater(name):
    print('%s ready to eat' %name)
    food_list = []
    while True:
        food = yield food_list
        food_list.append(food)
        print('%s ready to eat %s' %(name,food))
e = eater('xiaoming')
print(e)              #<generator object eater at 0x00000295EF99CF10>
e.send(None)          #xiaoming ready to eat  #必须先next,若直接send则会报错和 e.send(None)结果一致,相当于先初始化
print(e.send('rice')) #xiaoming ready to eat rice ['rice']
print(e.send('milk')) #xiaoming ready to eat milk ['rice', 'milk']

4.练习

1)用生成器实现range功能

def func(start,stop,step):
    while start < stop:
        yield start
        start+=step
res = func(1,10,2)

while True:
    try:
        print(next(res))
    except StopIteration:
        break

2)模拟管道,实现功能:tail -f access.log | grep '404'

import time
#tail 功能
def my_tail(file):
    with open(file,'rb') as f:
        f.seek(0,2) #直接调到文件末尾
        while True:
            line = f.readline()
            if line:
                yield line
            else:
                time.sleep(0.05)
#grep 功能
def my_grep(lines,pattern):
    for line in lines:
        line = line.decode('utf-8')
        if pattern in line:
            yield line
lines = my_tail('./access.log')
print(lines)        #<generator object my_tail at 0x000001F6DAF8CF68>
res = my_grep(lines,'404')
print(res)          #<generator object my_grep at 0x000001F6DAF8CFC0>

#print
for line in my_grep(my_tail('./access.log'),'404'): #res = my_grep(my_tail('./access.log'),'404')
    print(line.strip())
posted @ 2018-01-02 23:21  丢失固执  阅读(176)  评论(0编辑  收藏  举报