python 生成器和迭代器
一、迭代器
所谓的迭代器就能具有next方法的对象,调用next方法是,迭代器返回其下一个值,若没有值,则返回StopInteration异常,__iter__方法返回一个迭代器
注意:python 3.0中,迭代器实现的方法为__next__,而不是next
>>> class Fib: def __init__(self): self.a=0 self.b=1 def __iter__(self): return self def next(self): self.a,self.b=self.b,self.a+self.b if self.a>100:raise StopIteration return self.a
>>> fib=Fib() >>> fib.next() 1 >>> fib.next() 1 >>> fib.next() 2 >>> fib.next() 3 >>> fib.next() 5 >>> fib.next() 8 >>> fib.next() Traceback (most recent call last): File "<pyshell#177>", line 1, in <module> fib.next() File "<pyshell#169>", line 10, in next if self.a>10:raise StopIteration StopIteration >>>
生成list,
>>> fib=Fib() >>> list(fib) <__main__.Fib instance at 0x00000000034603C8> [1, 1, 2, 3, 5, 8] >>> list(fib) <__main__.Fib instance at 0x00000000034603C8> []
>>> fib=Fib() >>> fib.next() 1 >>> list(fib) <__main__.Fib instance at 0x00000000036075C8> [1, 2, 3, 5, 8]
生成的list和当前迭代点有关,python提供内建函数iter,从可迭代对象获得迭代器
>>> alist='abcde'
>>> blist=[1,2,3,4]
>>> clist=('c','d','e')
>>> dlist={'a':1,'b':2}
>>> ita=iter(a)
>>> itb=iter(blist)
>>> ita=iter(alist)
>>> itc=iter(clist)
>>> itd=iter(dlist)
>>> itb.next()
1
>>> itc.next()
'c'
>>> ita.next()
'a'
>>> itd.next()
'a'
>>> itd.next()
'b'
字典迭代的为key
二、生成器
包含yield的语句的函数称为生成器,除了名字不同以外,和普通的函数也有很大的差异,这就在于它不像普通的函数返回值,而是每次产生一个断点,激活后就重那里开始
生成器由2部分组成,生成器函数和生成器的迭代器,前者是def定义包含yield语句的函数,后者为函数返回的部分
#!/usr/bin/env python #-*- coding:utf-8 -*- def yi(alist): for sublist in alist: for el in sublist: print "before stop-point" try: yield el except StopIteration: print "itering is over" print "after stop-point"
>>> import yie_test >>> a=[[1,2],[3,4]] >>> dir(yie_test) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'yi'] >>> te=yie_test.yi(a) >>> te.next <method-wrapper 'next' of generator object at 0x7f3db05e8e10> >>> te.next() before stop-point 1 >>> te.next() after stop-point before stop-point 2 >>> te.next() after stop-point before stop-point 3可以看出在每次执行的时候在yield语句处停住,可以通过type命令查看yi()类型为generator
生成器其他方法:
send:外部域访问生成器的方法,需要在内部挂起生成器,yield作为表达式使用而不是语句,换句话说当生成器重新运行的时候,返回外部通过send发送的值
def repeater(value): while True: new=(yield value) if new is not None: value=new
>>> import yie_test >>> r=yie_test.repeater(10) >>> r.next() 10 >>> r.next() 10 >>> r.next() 10 >>> r.send(11) 11 >>> r.next() 11 >>> r.next() 11 >>> r.next() 11
close方法用于停止生成器
throw方法用于在生成器内部引发一个异常。