一、迭代器
实现一个迭代器,应满足如下条件:
- python2中,实现next()方法的类(python3可用__next__()取代)
- 可变对象,unhashable type
- 总是返回当前迭代位置之前的值(有限长度的迭代器,无法迭代最后值)
- 产生StopIteration异常,证明到达迭代器末尾
简单示例
#!/usr/bin/env python class SampleIter: """ sample iterator >>> sampleIter = SampleIter() >>> sampleIter.next() 'a' >>> sampleIter.next() 'b' >>> sampleIter.next() Traceback (most recent call last): ... StopIteration """ def __init__(self, start='a', end='c'): self.next_letter = start self.end = end def next(self): """In python3, better to use __next__""" if self.next_letter == self.end: raise StopIteration current = self.next_letter self.next_letter = chr(ord(current)+1) return current if __name__ == '__main__': import doctest doctest.testmod()
二、可迭代对象
能被for语句遍历的对象是可迭代的,一个迭代对象需要实现__iter__方法。
- 可迭代对象需要在__iter__方法里返回一个迭代器
- 同一个可迭代对象可以被迭代多次
- 通常将迭代器实现为可迭代对象
简单示例
class SampleIterable: """ sample iterator >>> sampleIterable = SampleIterable() >>> sampleIter = sampleIterable.__iter__() >>> sampleIter.next() 'a' >>> sampleIter.next() 'b' >>> sampleIter.next() Traceback (most recent call last): ... StopIteration >>> for letter in sampleIterable: ... letter 'a' 'b' """ def __init__(self, start='a', end='c'): self.start = start self.end = end def __iter__(self): return SampleIter(self.start, self.end)
三、生成器
生成器是迭代器的一种类型,不再用return关键字返回值,而是用yield关键字取代。
- 当调用包含yield的方法时,并不会直接执行方法,而是返回一个generator对象
- 函数执行到yield关键字的时候,会返回yield后面表达式的值,然后挂起方法直到下一次循环
简单代码
def sample_generator(): """ sample generator >>> g = (x for x in range(3)) >>> type(g) <type 'generator'> >>> d = {} >>> d[g] = 1 #no error,hashable type >>> type(sample_generator()) <type 'generator'> >>> for letter in sample_generator(): ... letter 'a' 'b' """ current = 'a' while current < 'c': yield current current = chr(ord(current)+1)
四、总结
通常,list能完成我们对序列化数据的所有需求。可是当我们处理大数据序列或者无限序列时,list这种将数据直接写入内存中处理方式就不再适用了。这种情况下,迭代器是一个很好的解决方案——它用一种lazy computation处理方式在需要时生成数据,消耗的内存空间微乎其微。