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 レコードが処理されました」を出力したいと考えています。コードの呼び出しを制御できないため、これはイテレータ内で行う必要があります。

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

whichから__iter__生成関数に変換することもできます (代わりに、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 に答える