(23)迭代器、生成器

*可迭代对象
list,tuple,dict,str,generator(生成器)

*迭代器
迭代器肯定是iterable类型的对象,它是包含有next(Python 2) 方法或者__next__(Python 3) 方法和__iter__(返回self)方法的一个特殊对象,可以对这样一个对象进行for loop循环访问。
对于实现next方法需要注意的是,当没有下一个元素的时候必须抛出StopIteration异常。
当遍历一个迭代器的时候,它会修改内部状态,导致你只能向前获取下一个元素,不能通过迭代器访问后面一个元素;也就是说当你通过迭代器访问了一个元素以后,在当前循环中不能后退继续访问该元素了,除非你重新生产迭代器对象进行遍历。
另外需要注意的是在迭代器中next方法是return下一个元素的值,不像下面介绍的生成器yield一个元素。

class Iterator_: 
   def __init__(self, s, e):  
       self.current = s  
       self.end = e  
   def __iter__(self): 
       return self 
   def next(self): 
       if self.current < self.end: 
           self.index = self.current 
           self.current += 1 
           return self.index 
       else: 
           raise StopIteration 
it = Iterator_(5, 8) 
for i in it:  
    print "iterator:" + str(i) 
#never print 
for i in it:  
    print "second iterator:" + str(i) 
#print again 
it = Iterator_(5, 8) 
for i in it:  
    print "second iterator:" + str(i) 
#输出 
iterator:5 
iterator:6 
iterator:7 
second iterator:5 
second iterator:6 
second iterator:7 

* 生成器
对于一个生成器它一定是一个迭代器,可以通过for loop进行访问其中的元素,但是一个迭代器却很明显的不一定是生成器。
定义迭代器有两种方式,第一个是使用yield关键词,另外一个是生成器表达式"()"。
对于一个方法在方法体里加上yield关键词就变成了生成器。yield作用就是返回一个生成器,它会保存当前函数状态,
记录下一次函数被调用next的时候运行状态。当函数没有下一次运行状态的时候,再继续调用next方法,这个时候StopIteration异常就被抛出。
print "generator" 
#first way  
my_generator = (x for x in range(3)) 
for i in my_generator: 
    print i 
#second way 
def Generator_(l): 
   n = 0  
   size = len(l) 
   while n < size: 
       yield l[n]    
       n += 1 
 
ge = Generator_([1, 2, 3])  
for g in ge:  
    print "generator:" + str(g) 

原文地址:https://www.cnblogs.com/toby2chen/p/8465016.html