10

当迭代器耗尽时,最后一次从迭代器返回一些东西的好方法是什么。我正在使用一个标志,但这很丑陋:

class Example():

    def __iter__(self):
        self.lst = [1,2,3]
        self.stop = False # <-- ugly            
        return self

    def next(self):
        if self.stop:  # <-- ugly
            raise StopIteration
        if len(self.lst) == 0:
            self.stop = True            
            return "one last time"
        return self.lst.pop()

背景:我从外部来源获取未知数量的字符串并将它们进一步发送给调用者。当这个过程结束时,我想发出一个字符串“x records processed”。我无法控制调用代码,所以这必须在我的迭代器中完成。

4

4 回答 4

6

也许您可以改用生成器函数:

def example():
    lst = [1, 2, 3]
    while lst:
        yield lst.pop()
    yield 'one last time'
于 2012-02-22T18:53:02.263 回答
6

你可以直接 yield from __iter__which 将它变成一个生成器函数(或者你可以按照 Dan 的建议编写一个生成器函数)。作为警告,这可能会误导滥用该next方法的人。

class Example():

    def __iter__(self):
        lst = [1,2,3]
        for i in reversed(lst):
            yield i
        yield "one last time"
于 2012-02-22T18:59:31.170 回答
1

不要退回一件多余的东西。这是一个坏主意,因为它不能很好地扩展。如果您既想求和又想计数怎么办?还是哈希和计数?迭代器是一个有状态的对象。好好利用它。

class Example( collections.Iterator ):
    def __iter__(self):
        self.lst = [1,2,3]
        self.count = 0       
        return self
    def next(self):
        if self.lst:
            self.count += 1
            return self.lst.pop()
        raise StopIteration()

像这样使用它。

my_iter= iter(Example())
for item in my_iterprin:
    print( item )

print( my_iter.count )
于 2012-02-22T19:19:20.457 回答
0

你可以这样做:

class Example():
    def __iter__(self):
        self.lst = [1, 2, 3]
        return self

    def next(self):
        try:
            return self.lst.pop()
        except IndexError:
            print "done iterating"
            raise StopIteration

>>> for i in Example():
...   print i
...
3
2
1
done iterating

在您的实际代码中,您可能需要更改您正在捕获的异常类型,但这种格式应该仍然适用。

于 2012-02-22T18:55:49.047 回答