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 iterable my_obj = MyClass()
# Create the iterator object from the iterable my_it = iter (my_obj)
for i in range ( 7 ):
print ( next (my_it))
|
結果は以下の通りです。
Call to __iter__() Call to __next__() 1 Call to __next__() 2 Call to __next__() 3 Call to __next__() 4 Call to __next__() 5 Call to __next__() 6 Call 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 の記事