この連載では、Pythonについて色々な形で再学習に取り組んでいます。前回の記事はこちらになります。
前回は、カレンダーについて見ていきました。calendarモジュールを使ってカレンダーの表示ができます。
今回は、イテレータについてです。前回の後半でcalendarモジュールを使って、日付データのイテレータを作成できる旨ご紹介しました。「イテレータ」とは何なんでしょうか。
イテラブル
for文の説明をした記事で、以下のように説明しました。
要素を取り出す順番が決まっているオブジェクトを、イテラブルなオブジェクトといいます。以下のように記述します。
for 変数 in イテラブルなオブジェクト: # 処理
ここでいう「イテラブルなオブジェクト(以下、イテラブル)」とは、「イテレータを生成できるオブジェクト」のことです。そして「イテレータ」とは、「要素を1つずつ取り出せるオブジェクト」なのです。
先のfor文の例の様にイテラブルを配置すると、自動的にイテレータが生成され、要素を1つずつ取り出して処理します。イテレータ自身もイテラブルです。よって、for文は以下の様にも書けます。
for 変数 in イテレータ: # 処理
dir()関数を使用して確認すると、イテラブルには必ず特殊メソッド「iterメソッド」があります。iterメソッドを使用することで、イテレータを生成します。
イテレータにも(イテレータ自身もイテラブルなので)iterメソッドがあります。加えてイテレータには「nextメソッド」があります。nextメソッドを使用すると、イテレータの次の要素を取得できます。
for文は、これらの特殊メソッドを使用してイテレータから1つずつ要素を取り出して処理しています。
イテレータの作成
イテラブルを指定してiter()関数を使用すると、iterメソッドが呼び出されてイテレータが作成されます。イテレータを指定してnext()関数を使用すると、nextメソッドが呼び出されてイテレータの次の要素が取得できます。
以下はiter()関数とnext()関数の使用例です。
it = iter([0,1,2]) # イテラブル(リスト)からイテレータを生成 print(next(it)) # 0 を返す print(next(it)) # 1 を返す print(next(it)) # 2 を返す print(next(it)) # 例外 StopIteration が発生する
リストから要素を1つずつ取得しています。最後まで取得すると、次は例外「StopIteration」が発生します。StopIterationは、イテレータの要素が最後まで取り出された場合の例外です。
リストのnextメソッド
上の例ではリストからイテレータを生成しています。でも、リスト自体にはnextメソッドが定義されていません。実は、iter()関数が実行された時(iterメソッドを呼び出したとき)、リスト専用の内部イテレータオブジェクト(リストイテレータオブジェクト)が生成されるのです。
iterメソッドは、このオブジェクト内に定義されています。
it = iter([0,1,2]) print(type(it)) # <class 'list_iterator'> を返す
イテレータを作る
クラスにiterメソッド、nextメソッドを記述すれば、独自のイテレータを作成できます。以下は作成例です。
class CountUp: def __init__(self, max_value): # カウント最大値を設定 self.max_value = max_value def __iter__(self): # カウントを初期化してイテレータを生成 self.current = 1 return self def __next__(self): if self.current <= self.max_value: # 現在の値を返してカウントアップ result = self.current self.current += 1 return result else: # 最大値を超えたらStopIteration例外を発生させる raise StopIteration # イテレータの作成 my_iterable = CountUp(5) # forループで使用できる for value in my_iterable: print(value , end = " ") # 1 2 3 4 5 を返す
御覧の通り、イテレータとして動作していることがわかります。「raise StopIteration」は、例外「StopIteration」を発生させます。
次回はジェネレーター
いかがでしょうか。イテラブル、イテレータの仕組みがわかってきました。ところで、似たような仕組みに「ジェネレーター」なるものがあります。次回はこちらを取り上げようと思います。お楽しみに!!