构建一个基本的Python迭代器
如何在python中创建一个迭代函数(或者迭代器对象)?
解决方案
回答
首先,itertools模块在各种情况下都非常有用,在这种情况下,迭代器将是有用的,但是这里是在python中创建迭代器所需的全部:
yield
那不是很酷吗? Yield可以用来代替函数中的正常收益。它返回的对象是相同的,但是它不会破坏状态并退出,而是为我们要执行下一次迭代保存状态。这是直接从itertools函数列表中提取的示例:
def count(n=0): while True: yield n n += 1
如函数说明中所述(它是itertools模块中的count()函数...),它生成一个迭代器,该迭代器返回以n开头的连续整数。
生成器表达式是蠕虫(真棒蠕虫!)的另一种形式。可以使用它们代替列表推导来节省内存(列表推导会在内存中创建一个列表,如果未分配给变量,该列表在使用后会被销毁,但是生成器表达式可以创建一个Generator对象...说迭代器)。这是生成器表达式定义的示例:
gen = (n for n in xrange(0,11))
这与上面的迭代器定义非常相似,不同之处在于整个范围的预定范围是0到10.
我刚刚找到了xrange()(应该是我以前没看过……)并将其添加到上述示例中。 xrange()是range()的可迭代版本,其优点是不预先构建列表。如果我们要遍历庞大的数据集并且只有那么多的内存可以进行访问,这将非常有用。
回答
python中的迭代器对象符合迭代器协议,这基本上意味着它们提供了两种方法:__iter __()和next()。 __iter__
返回迭代器对象,并在循环开始时隐式调用。 " next()"方法返回下一个值,并在每次循环增量时隐式调用。当没有更多值要返回时,next()
会引发StopIteration异常,该异常是通过循环构造以停止迭代来隐式捕获的。
这是一个简单的计数器示例:
class Counter: def __init__(self, low, high): self.current = low self.high = high def __iter__(self): return self def next(self): # Python 3: def __next__(self) if self.current > self.high: raise StopIteration else: self.current += 1 return self.current - 1 for c in Counter(3, 8): print c
这将打印:
3 4 5 6 7 8
如上一个答案所述,使用生成器编写起来更容易:
def counter(low, high): current = low while current <= high: yield current current += 1 for c in counter(3, 8): print c
打印的输出将是相同的。在内部,生成器对象支持迭代器协议,并且执行与类Counter大致相似的操作。
David Mertz的文章Iterators和Simple Generators是一个很好的介绍。