1. 可迭代对象
from collection import Iterableclass Iterable(metaclass=ABCMeta):...def __iter__(self): # 只实现了__iter__ 方法while False:yield None
能够在 for ... in obj:中使用的对象(obj)就是一个可迭代对象。
2. 迭代器
from collections import Iteratorclass Iterator(Iterable): # Iterable的子类 ...def __next__(self): # 实现了 __next__raise StopIterationdef __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 = dataself.index = len(data)def __iter__(self):return selfdef __next__(self): # py2: next()方法if self.index == 0:raise StopIterationself.index = self.index - 1return 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) - 1min_len = -1for 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. 场景
在使用中分配内存,而不是一次分配所有的内存。