1. 可迭代对象
from collection import Iterable class Iterable(metaclass=ABCMeta): ... def __iter__(self): # 只实现了__iter__ 方法 while False: yield None
能够在 for ... in obj:中使用的对象(obj)就是一个可迭代对象。
2. 迭代器
from collections import Iterator class Iterator(Iterable): # Iterable的子类 ... def __next__(self): # 实现了 __next__ raise StopIteration def __iter__(self): # 也实现了 __iter__ return self
能够使用.next() 或者 .__next__() 方法,在没有下一个元素时,返回 StopIteration 异常的对象,都是迭代器,可迭代对象转换成迭代器的方法是: iter(obj) 返回的就是一个迭代器。
>>> a = [] >>> a [] >>> s = iter(a) >>> s <list_iterator object at 0x7feac859b048> >>> s.next() # 这个方法不存在,抛出的是属性错误异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list_iterator' object has no attribute 'next' >>> s.__next__ <method-wrapper '__next__' of list_iterator object at 0x7feac859b048> >>> s.__next__() # 这个方法存在,抛出的是 StopIteration 异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>
实现自己的迭代器:
class Reverse: def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): # py2: next()方法 if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] rev = Reverse('timlinux') for char in rev: print(char)
3. 生成器yield
生成器(generator)是用来构造迭代器的一种语法工具,通过使用 yield 关键字来代替 return,并自动构建好 __iter__() 和 __next__() 两个方法:
- yield 关键字的位置将发生 return 操作
- yield 关键字存在的函数中,将具有 __iter__, __next__ 函数
def reverse(data): max_len = len(data) - 1 min_len = -1 for index in range(max_len, min_len, -1): yield data[index] x = reverse('timlinux') dir(x) # py3: 返回的对象有 __iter__, __next__ 方法 # py2: 返回的对象有 __iter__, next 方法
列表生成式中的 [] 换成 (),得到的对象就不再是一个列表,而是一个生成器:
>>> L = [x*x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x*x for x in range(10)) >>> g <generator object <genexpr> at 0x7f9a8dd48a00>
4. 场景
在使用中分配内存,而不是一次分配所有的内存。