首页 > 代码库 > python高级编程之迭代器与生成器
python高级编程之迭代器与生成器
# -*- coding: utf-8 -*-
# python:2.x
__author__ = ‘Administrator‘
#迭代器与生成器
#---------------------------------------
#迭代器基于2个方法
"""
next:返回容器下一个项目
__iter__:返回迭代器本身
"""
#通过内建函数和序列来创建
i=iter(‘abc‘)
print i.next()#a
print i.next()#b
print i.next()#c
#print i.next()异常StopIteration
#当序列遍历完之后,出现StopIteration异常,与循环进行兼容,可以通过 使用next方法类来得到结果
class Miter(object):
def __init__(self,a):
self.a=a
def next(self):
if self.a==0:
raise StopIteration
self.a-=1
return self.a
def __iter__(self):
return self
for el in Miter(4):
print el
#注意:迭代器是底层特性和概念,一般情况下,程序代码中可以没有它们
#------------------------------
#生成器
#特点是:简单,高效,基于yield指令,可以暂停一个函数并返回中间结果,必须是可以恢复
def fib():
a,b=0,1
while True:
yield b
a,b=b,a+b
f=fib()
print f.next()#1
print f.next()#1
print f.next()#2
print [f.next() for i in range(10)]#返回特殊的迭代器,也就是generator对象,请看:http://www.cnblogs.com/itech/archive/2011/01/19/1939119.html
#重点:当需要一个将返回一个序列或者在循环中执行的函数时,就考虑生成器
import tokenize
#官方文档:https://docs.python.org/2/library/tokenize.html
reader=open(‘a1.py‘,‘r‘).next
tokens=tokenize.generate_tokens(reader)
print tokens.next()#(53, ‘# -*- coding: cp936 -*-‘, (1, 0), (1, 23), ‘# -*- coding: cp936 -*-\n‘)
#注意:因为没有高级编程上面那个文件,所以只能使用自己的文件
print tokens.next()#(54, ‘\n‘, (1, 23), (1, 24), ‘# -*- coding: cp936 -*-\n‘)
print tokens.next()#(1, ‘def‘, (2, 0), (2, 3), ‘def a(a1):\n‘)
print tokens.next()#(1, ‘a‘, (2, 4), (2, 5), ‘def a(a1):\n‘)
"""
open()函数进行遍历了文件中每一行,generate_tokens()则在一个管道中对其进行遍历,完成一些额外的工作
"""
#例子:说明函数用来在序列上面定义一个转换,然后被链接起来应用 ,每次调用将处理一个元素,并返回它的结果
def power(values):
for values2 in values:
print values2
yield values2
def addr(values):
for value in values:
print value
if value%2==0:
yield value+3
else:
yield value+2
el=[1,4,7,9,12,19]
res=addr(power(el))
print res.next()#1,1,3
#注意
"""
保持代码简单,而不是数据{
拥有许多简单的处理序列值的可迭代函数,要比一个复杂的,每次计算一个值的函数更好一些}
"""
#python引入的与生成器最后一个特性是提供了与next()方法调用的代码交互功能,yield变成一个表达式,而一个值 可以通过名为send新方法来传递
def psy():
print ‘pleass tell me your problems‘
while True:
anwer=(yield)
if anwer.endswith(‘?‘):
print ("don‘t ask your self")
elif ‘good‘ in anwer:
print ‘good gon‘
elif ‘bad‘ in anwer:
print ‘bad‘
Pay=psy()
Pay.next()#pleass tell me your problems
Pay.send(‘i fell bad‘)#bad
Pay.send(‘why i shou ?‘)#don‘t ask your self
#原理
"""
send的工作机制与next一样,但需要yield将变成能够返回传说的值,同时还有throw和close函数
throw允许客户端代码传入要招聘的任何类型的异常
close的工作方式是相同的,但是将会招聘一个特定的异常<GeneartorExit>,在这样的情况下,生成器函数必须再次GeneartorExit
或者StopIteration异常
"""
#典型生成器模板
def My_GeneartorExit():
try:
yield ‘something‘
except ValueError:
yield ‘dealing with the exception‘
finally:
print ‘ok clean‘
my=My_GeneartorExit()
print my.next()#ok clean和something
print my.throw(ValueError(‘mean mean mean‘))#dealing with the exception
my.close()#ok clean
#print my.next()StopIteration
#说明
"""
finally在之前版本是不允许使用的,它将捕获任何未被捕获的close和throw调用,是完成清理工作的推荐方式,
GeneartorExit异常在生成器中是无法被捕获的,因为它被编译器用来确定调用close时是否正常退出,如果有代码与这个异常关联,那么解释程序将抛出一个系统错误
并退出
"""