构建一个基本的Python迭代器

时间:2020-03-05 18:41:21  来源:igfitidea点击:

如何在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是一个很好的介绍。