Pythonのイテレータは、反復処理可能なオブジェクトです。
このような反復をサポートするあらゆる種類のオブジェクトはイテレータと呼ばれます。
さて、あなたは混乱するかもしれません。
iterableという別のオブジェクトが存在します。
それは何でしょうか?見てみましょう。
イテレータとイテラブル
イテレート可能なオブジェクトは、反復処理が可能なオブジェクトです。
つまり、イテレータを使ってこのオブジェクトの中を移動することができる。
イテレート可能なオブジェクトの例としては、タプル、リスト、文字列、配列などがあります。
イテレート可能なオブジェクトからイテレータを生成するには、iter() メソッドを用いる。
iterable_list = [1, 2, 3]
iterable_string = "Hello"
iterator_1 = iter(iterable_list)
iterator_2 = iter(iterable_string)
print(iterator_1, type(iterator_1))
print(iterator_2, type(iterator_2))
|
結果は以下の通りです。
<list_iterator object at 0x7f887b01aed0> <class 'list_iterator'>
<str_iterator object at 0x7f887b01af50> <class 'str_iterator'>
|
出力は、リストと文字列の2つのイテレータが作成されたことを示しています。
ここで、イテレータオブジェクトがサポートするメソッドを見てみましょう。
Python イテレータメソッド
イテレータオブジェクトには iter() と next() と呼ばれる2つの特別なメソッドがあります。
iter()`メソッドは、イテレートからPythonイテレータオブジェクトを取得するために使用されました。
次に、イテレータを走査するために、 next() メソッドを使用してイテレータブルの次の要素を取得します。
形式です。
next_iterable_object = next(iterator)
|
移動する要素がなくなると、これは終了し、 StopIteration 例外を発生させます。
これを説明するために、リストイテレータのすべての要素を表示してみましょう。
>>> iterable_list = [1, 2, 3]
>>> iterator_1 = iter(iterable_list)
>>> next(iterator_1)
1>>> next(iterator_1)
2>>> next(iterator_1)
3>>> next(iterator_1)
Traceback (most recent call last): File "<stdin>", line 1, in <module>
StopIteration |
見ての通り、イテレータの長さを超えると、確かに StopIteration Exception を発生させます。
さて、次のステップに進みましょう。
この記事もチェック:Pythonでクラスのすべてのメソッドを一覧として表示する方法
Python で独自のイテレータを構築する
どんなイテレータオブジェクトも、走査可能な要素数を持っています。
しかし、独自のイテレータを作るにはどうしたらよいのでしょうか?独自のクラスを作成する必要があります。
Pythonでは、イテレータを作るには、イテレータプロトコルと呼ばれるプロトコルが必要です。
このプロトコルには __iter__() と __next__() という特定のメソッドがあり、一般的なイテレータのメソッドと似ていますが、クラスの中にあるため、区別を示すためにこの記号を前置・後置しています。
iter()とnext()メソッドは内部でこれらのメソッドを呼び出すので、イテレータを作るには、クラスの内部でiter()とnext()` メソッドを独自に定義する必要があります。
リストだけを走査し、要素の数が 5 より大きい場合に StopIteration Exception を発生させる単純なイテレータを作成してみましょう。
また、next() メソッドで、これまでにイテレートした要素数を表示することにします。
class MyClass():
def __init__(self):
self.counter = 0
# Set the limit
self.limit = 5
def __iter__(self):
# The iter() method internally calls this
print('Call to __iter__()')
return self
def __next__(self):
print('Call to __next__()')
if self.counter > self.limit:
raise StopIteration
else:
# Increment counter and return it
self.counter += 1
return self.counter
# Create the iterablemy_obj = MyClass()
# Create the iterator object from the iterablemy_it = iter(my_obj)
for i in range(7):
print(next(my_it))
|
結果は以下の通りです。
Call to __iter__()Call to __next__()1Call to __next__()2Call to __next__()3Call to __next__()4Call to __next__()5Call to __next__()6Call to __next__()Traceback (most recent call last): File "iter.py", line 29, in <module>
print(next(my_it))
File "iter.py", line 15, in __next__
raise StopIteration
StopIteration |
ここでは、1から6までの数字を表示していますが、次の呼び出しでは、限界を超えたため、 StopIteration 例外を発生させます。
私たちは独自のイテレータを作りました。
まとめ
この記事を読んで、イテレータについてよく理解し、この概念に関する疑問が解消されたことでしょう。
もしそうでなければ、下のコメント欄で質問してください。
参考文献
- イテレータに関する JournalDev の記事