Python中Iterator迭代器的使用杂谈
迭代器是一种支持next()操作的对象。它包含一组元素,当执行next()操作时,返回其中一个元素;当所有元素都被返回后,生成一个StopIteration异常。 >>>a=[1,2,3] >>>ia=iter(a) >>>next(ia) 1 >>>next(ia) 2 >>>next(ia) 3 >>>next(ia) Traceback (most recent call last): File "<stdin>",line 1,in <module> StopIteration ite()可以接受多种Python对象为参数,比如list,tuple,dict,set等,并将其转化为迭代器。迭代器可以用于for语句或in语句中。很多常用操作也是支持迭代器的,比如sum(),max()等。 >>> b=[4,5,6] >>> ib=iter(b) >>> for x in ib: ... print(x) ... 4 5 6 >>> ic=iter(b) >>> sum(ic) 15 >>> id=iter(b) >>> max(ic) 6 毋庸置疑,迭代器有很多好处: 1.“流式”数据处理方式减少内存消耗: for text_line in open("xx.txt"): print text_line 2.或者对xml文件进行处理的时候: tree = etree.iterparse(xml,['start','end']) for event,elem in tree: if event == "end" result = etree.tostring(elem) elem.clear() print result 内置函数open返回的file对象和etree.iterparse序列化的xml tree都是可迭代对象,能够让我们渐进式地对文件的内容进行处理。 3.支持方便用for语句对数据进行消费: for i in [1,3,4] print i, 简单了解了一下迭代器的好处后,我们正正经经的聊聊python的迭代器模式。 可迭代对象:对象里面包含__iter()__方法的实现,对象的iter函数经调用之后会返回一个迭代器,里面包含具体数据获取的实现。 class iterable_range: def __init__(self,n): self.n = n def __iter__(self): return my_range_iterator(self.n) class my_range_iterator: def __init__(self,n): self.i = 0 self.n = n def next(self): if self.i < self.n: i = self.i self.i += 1 print 'iterator get number:',i return i else: raise StopIteration() 例子中的iterable_range是一个可迭代对象,所以我们也能够对它用for语句来进行迭代: temp = my_range(10) for item in temp: print item, 输出: my iterator get number: 0 0 my iterator get number: 1 1 my iterator get number: 2 2 my iterator get number: 3 3 my iterator get number: 4 4 my iterator get number: 5 5 my iterator get number: 6 6 my iterator get number: 7 7 my iterator get number: 8 8 my iterator get number: 9 9 大家可以仔细地看一下输出的日志:
可迭代对象其实更像是整个迭代器模式模式的上层,像一种约束一种契约一种规范,它能够保证自己能够返回一个在实际工作中干活的迭代器对象。for、sum等接受一个可迭代对象的方法都是遵循这样的规范:调用对象的__iter__函数,返回迭代器,对迭代器对象返回的每个值进行处理抑或需要一些汇总的操作。拿for举个例子: iterator_object = iterable_object.__iter__() while True: try: value = iterator_object.next() except StopIteration: # StopIteration exception is raised after last element break # loop code print value for这个语法糖背后的逻辑差不多就是上面例子中代码所示的那样:首先获取可迭代对象返回的迭代器对象,然后调用迭代器对象的next方法获取每个值,在获取值的过程中随时检测边界-也就是检查是否抛出了StopIteration这样的错误,如果迭代器对象抛出错误则迭代停止(note:从这个例子可以看出,对于那些接受可迭代对象的方法,如果我们传一个单纯的迭代器对象其实也是无法工作的,可能会报出类似于TypeError: iteration over non-sequence的错误)。 class my_range_iterator: def __init__(self,n): self.i = 0 self.n = n def __iter__(self): return self def next(self): if self.i < self.n: i = self.i self.i += 1 print 'my iterator get number:',i return i else: raise StopIteration() for item in my_range_iterator(10): print item 输出:
my iterator get number: 0 0 my iterator get number: 1 1 my iterator get number: 2 2 my iterator get number: 3 3 my iterator get number: 4 4 my iterator get number: 5 5 my iterator get number: 6 6 my iterator get number: 7 7 my iterator get number: 8 8 my iterator get number: 9 9 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |