基本的なイテレータを構築するにはどうすればいいですか? 質問する

基本的なイテレータを構築するにはどうすればいいですか? 質問する

どうすれば作成できますか?反復子Python では?

たとえば、インスタンスに論理的にいくつかの値が「含まれる」クラスがあるとします。

class Example:
    def __init__(self, values):
        self.values = values

次のようなコードを書けるようになりたいです:

e = Example([1, 2, 3])
# Each time through the loop, expose one of the values from e.values
for value in e:
    print("The example object contains", value)

より一般的には、イテレータは値の取得元を制御したり、インスタンスの特定の属性を考慮するのではなく、その場で値を計算したりできる必要があります。

ベストアンサー1

Python のイテレータ オブジェクトはイテレータ プロトコルに準拠しており、基本的には と の 2 つのメソッドを提供し__iter__()ます__next__()

  • __iter__反復子オブジェクトを返し、ループの開始時に暗黙的に呼び出されます。

  • この__next__()メソッドは次の値を返し、ループの増分ごとに暗黙的に呼び出されます。このメソッドは、返す値がなくなったときに StopIteration 例外を発生させます。これは、反復処理を停止するためにループ構造によって暗黙的にキャプチャされます。

カウンターの簡単な例を次に示します。

class Counter:
    def __init__(self, low, high):
        self.current = low - 1
        self.high = high

    def __iter__(self):
        return self

    def __next__(self): # Python 2: def next(self)
        self.current += 1
        if self.current < self.high:
            return self.current
        raise StopIteration


for c in Counter(3, 9):
    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, 9):
    print(c)

印刷される出力は同じになります。内部的には、ジェネレーター オブジェクトはイテレータ プロトコルをサポートし、Counter クラスとほぼ同様の処理を実行します。

デイヴィッド・メルツの記事、イテレータとシンプルなジェネレータ、これはかなり良い紹介です。

おすすめ記事