Pythonイテレータの作り方を徹底解説!初心者向け完全ガイド
Pythonでイテレータを作成する方法:完全ガイド
Pythonにおいて、イテレータはいたるところで使われています。基礎を学ぶだけでも、「イテレータ」や「イテラブル(反復可能オブジェクト)」という言葉に必ず出会うほどです。
イテレータとは、反復処理(イテレーション)が可能なオブジェクトのことです。Pythonには最初から反復可能な組み込みオブジェクトが多数用意されていますが、自分で独自のイテレータを定義することもできます。
このガイドでは、Pythonのイテレータとは何か、どのように動作するのか、そしてコード内でどう活用できるのかを解説します。実際に独自のイテレータを作成しながら、その核心的な仕組みを学んでいきましょう。なお、本ガイドのコードはPython 3.x環境で動作します。
イテレータとは何か?
イテレータとは、反復処理を行えるオブジェクトであり、そのオブジェクトからデータを1つずつ順番に取り出すことができます。
あるオブジェクトがイテラブルかどうかを確認する最も簡単な方法は、forループで回してみることです。ループできれば、それはイテラブルだということになります。文字列、リスト、タプル、辞書などは、イテラブルな組み込みデータ型の代表例です。
Pythonのイテレータオブジェクトには、次の2つのメソッドが必要です。
__iter__():イテレータ自身を取得するためのメソッド__next__():次の値を取得するためのメソッド
これらのメソッド名に使われているアンダースコア2つ(__)は、特別な関数(特殊メソッド)であることを示しています。イテレータを定義するには、この2つの特殊メソッドを使う必要があります。この2つを合わせて「イテレータプロトコル」と呼びます。
無限イテレータの作り方
まずは基本から始めましょう。ここでは「無限イテレータ」を作成します。これは最もシンプルなタイプのイテレータで、シンプルすぎるほど永遠に処理が続いてしまいます(この問題は後ほど解決します)。
まず、Cakesというクラスを定義します。これが私たちのイテレータクラスになります。
class Cakes:
def __init__(self, value):
self.value = value
__init__メソッドは、クラスのオブジェクトが生成された瞬間に実行されるメソッドで、「コンストラクタ」と呼ばれます。この例では、__init__メソッドはvalueという1つの値を受け取ります。
次に、イテレータプロトコルを作成します。
def __iter__(self):
return self
def __next__(self):
return self.value
__iter__メソッドはイテレータオブジェクトを返します。__next__メソッドは、指定したイテラブルオブジェクトから次の値を取得する役割を担います。
ここまでのコードが正しく動くか確認してみましょう。次のようにクラスのオブジェクトを定義します。
cake = Cakes(["Vanilla Sponge"])
順調ですね。「あれ、このコードは何も表示しないの?」と思った方もいるかもしれません。それは、このクラスがまだイテレータを返すだけで、何も処理を実行していないからです。
イテレータが正しく機能しているかを確かめるには、実際に反復処理を行う必要があります。for-inループを使ってみましょう。
for c in cake:
print(c)
実行結果:
Vanilla Sponge
Vanilla Sponge
…
バニラスポンジの呪い!コンソールに延々と同じ文字列が出力され続けます。一体何が起きているのでしょうか?実は、これで最初のイテレータの作成に成功したのです。非常にシンプルですが、ちゃんと動いています。
for-inループによるイテレータのテスト
イテレータをより実用的なものにする前に、for-inループの仕組みをおさらいしておきましょう。先ほどの例では、コードをテストするために次のようなfor-inループを書きました。
for c in cake:
print(c)
for-inループは、まず__iter__()メソッドを使ってオブジェクトのイテレータを取得します。その後、値がなくなるまで__next__()を呼び出し続けます。
for-inループは、シンプルなwhileループだと考えると分かりやすいでしょう。イテレータが返せる値がある限り、for-inループはその値を返し続けます。
実用的なイテレータの作成
先ほどのイテレータはあまり実用的ではありませんでした。同じ値を出力し続けるだけだからです。とはいえ、立派なイテレータであることには変わりありません。イテラブル内のすべてのオブジェクトを読み取る能力を持っています。
今度は、Pythonの配列(リスト)を反復処理するイテレータを作成します。この配列にはケーキのリストが入っています。
イテレータが無限に繰り返さないようにするために、イテラブル内の要素数と、イテレータが実行された回数を記録します。こうすることで、すべての要素を処理し終えた時点でイテレータを停止できます。
新しいPythonファイルを開いて、以下のコードを貼り付けてください。
class Cakes:
def __init__(self, value):
self.value = value
self.max = len(value)
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count < self.max:
to_return = self.value[self.count]
self.count += 1
return to_return
else:
raise StopIteration
このイテレータは前のものより少し複雑です。だからこそ、まず無限イテレータから始めたのです。このイテレータでは、3つの値を初期化しています。
- value:反復処理したい対象のアイテム
- max:イテラブル内の要素数
- count:イテレータが実行された回数
__next__()メソッドにはif文を追加しました。この条件式は、イテレータの実行回数(count)が、反復処理すべき要素数(max)より少ないかどうかをチェックします。
countがmaxより小さい場合、イテレータはイテラブルオブジェクトから次の値を取り出します。その後、count変数に1を加算して、残りの反復回数を追跡できるようにします。そして、取り出した値を返します。
重要なポイントとして、count変数をインクリメントする前に、to_return変数に値を代入しています。これにより、現在のイテレーションで正しい値にアクセスできるようになります。
リスト内のすべての要素を処理し終えると、StopIterationという例外が発生します。これにより、リストの全要素を処理し終えた時点でプログラムが適切に停止します。
それでは、イテレータが正しく動作するか確認してみましょう。メインプログラムに以下のコードを追加して実行してください。
cake = Cakes(["Vanilla Sponge"])
for c in cake:
print(c)
実行結果:
Vanilla Sponge
リストにもう少し要素を追加して、どうなるか見てみましょう。
cake = Cakes(["Vanilla Sponge", "Carrot", "Coffee"])
for c in cake:
print(c)
実行結果:
Vanilla Sponge
Carrot
Coffee
成功です!ケーキのリストを順番にループ処理するイテレータを作成できました。ここまで読み進めたあなたには、ケーキ――少なくともカップケーキ1個――くらいのご褒美があってもいいはずです。
まとめ
イテレータを使えば、反復処理可能なオブジェクトを作成できます。イテレータは、リストや文字列などのイテラブルオブジェクトをループ処理し、特定のアクションを実行することができます。
挑戦してみたくはありませんか?数字のリストをループ処理して、各数値を2倍にして返すイテレータを作ってみてください。
このイテレータのコードは、先ほどの例とよく似ています。イテレータプロトコルを使う点は同じですが、メインプログラムに値を返す前に、リスト内の各数値を2倍にする処理を追加する必要があります。
これで、あなたもPythonでプロのように独自のイテレータを書く準備が整いました!
-
Pythonインタープリターとは?仕組みと初心者向けオンライン環境を徹底解説
Pythonは学びやすいプログラミング言語として知られています。その理由のひとつが、自分のマシンに正しいバージョンのPythonをインストールしなくても、オンラインで利用できるPythonインタープリターが数多く存在する点です。本記事では、Pythonインタープリターの仕組みについて解説し、初心者にも使いやすい人気のオンラインインタープリターをご紹介します。 Pythonプログラムはどのように実行されるのか? PythonはJavaと同様に、純粋なインタプリタ言語ともコンパイラ言語とも分類できず、両方の性質を併せ持っています。 ここでいう「コンパイル」とは、特定のプラットフォームに依存し
-
Pythonの辞書values()メソッド徹底解説:値の取得から活用まで
Pythonの辞書(ディクショナリ)におけるvalues()メソッドは、辞書に格納されているすべての値を含むオブジェクトを返します。辞書のキーではなく値だけを扱いたい場合に非常に便利なメソッドです。また、後から辞書の内容を変更すると、values()が返すデータも自動的に新しい状態へ反映されます。 Pythonで開発を行っていると、データを辞書として保存したい場面はよくあります。たとえば、レストラン管理システムを構築している場合、各注文の情報を辞書に格納することになるでしょう。 そこで疑問になるのが「辞書に保存した値はどうやって取り出せばいいのか?」という点です。ここで活躍するのが、Pyt