【初心者にもわかりやすく】Pythonのイテレータについて、その基本とfor文の仕組みを解説

Pythonのイテレータとは?その基本をfor文の仕組みとあわせて解説

今回のPython初心者向け解説は、イテレータ(iterator)です。わかるようでわからない・・・そんなPythonのプログラミング用語の1つですが、その基本的な部分だけをできるだけわかりやすく説明しようとがんばりますので、どうかみなさんも少しがんばって読んでみてください。

英語の「iterate」の意味

まず言葉の意味を確認しておきましょう。次のようになります。

単語 品詞 意味
iterate(発音:イテレイト)動詞繰り返す
iterator(発音:イテレーター)名詞繰り返しや反復をさせるもの

このようにもともとは英語の動詞として普通に存在する「iterate」という言葉があって、そこからプログラミングの世界独特の用語として「iterator」という名詞が創造され(?)ました。iteratorはプログラミングの専門用語としての言葉なので、普通の会話や英文で登場することはまずないでしょう。

なお、英語の動詞で「~ate」で終わるものは、名詞化の1つとして「~ator(~する人)」という形になるものが多いです。たとえば、「illustrate(イラストレイト)」→「illustrator(イラストレーターを描く人)」などです。

英語の発音上または普通のカタカナ表記上では、普通はイテレーターというように「ター」となるのですが、コンピューターの世界では語尾を伸ばさずに表記するのが普通らしいので、以下「イテレーター」ではなく、「イテレータ」と書いていきます。また、イテレータもPythonのオブジェクトの1つですが、イテレータオブジェクトを省略して単にイテレータと書いていきます。

Pythonのイテレータ(iterator)とは?イテレータであるための条件

Pythonのイテレータとは。次の2つの条件を満たすオブジェクトのことです。

  • __iter__()メソッドがあること
  • __next__()メソッドがあること

これら2つのメソッドはもともと最初からPythonで用意されているもので、これら2つとも持っていることがイテレータの条件です。逆にいえば、これら2つのメソッドさえ持っていればイテレータとなります。

次にこれら2つのメソッドについて簡単にその機能を見てみましょう。

__iter__()メソッドと__next__()メソッドとは?

これら2つのメソッドはそれぞれ次のような機能を持ちます。

メソッド(書き方) 機能
オブジェクト.__iter__()オブジェクトからイテレータを作る。ただしそのオブジェクトがそもそもイテレータだった場合は、そのイテレータであるオブジェクトそのものを返します
イテレータ.__next__()イテレータの各要素から1つずつ要素取り出して、要素がなくなればStopIteration 例外を返す。

そして上述のように、これら2つのメソッドを2つとも有しているオブジェクトがイテレータです。各メソッドの前にあるオブジェクトの型が異なることに注意してください。__next__()メソッドの対象となるオブジェクトはイテレータです。

上表のように__iter__()メソッドは、

対象となるオブジェクト.__iter__()

という書き方で使いますが、対象となるオブジェクトの種類によって大きく2つに機能が別れます。

オブジェクトの種類 機能
イテレータイテレータであるオブジェクトそのものを返す
それ意外
(ただし__iter__()メソッドを備えるもの)
オブジェクトのイテレータを新しく作成

このようにオブジェクトの種類によって機能が変化する点に注意してください。

具体例:for文とリストオブジェクトの場合

さて実際に初歩的なコードの具体例から、イテレータの基本的理解を深めていきましょう。

リスト型オブジェクトがイテレータではないことを確認


  new_list=["A", "B", "C"]
  for i in new_list:
      print(i)

まずは、このリスト型オブジェクトである「new_list」というリストについて確認しましょう。

インデックス番号(何番目の要素かという情報) 中身
0Aという文字列データ
1Bという文字列データ
2Cという文字列データ

これがnew_listの構造になっています。このリスト型オブジェクトが「イテレータではない」ことを確認してみましょう。

イテレータは__iter__メソッドと__next__メソッドとの両方を持つのが条件でしたので、それら2つも持つかどうか調べてみましょう。そのためには、Pyhonのdir関数を使います。このdir関数はオブジェクトがどのような属性や情報を持っているのかを示してくれるものです。

print('__iter__' in dir(new_list))

この場合は「True」が出力されます。つまり、new_listというリスト型オブジェクトは、__iter__()メソッドを持っているということです。

print('__next__' in dir(new_list))

逆にこれは「False」が出力されます。つまり、new_listというリスト型オブジェクトは、__next__()メソッドを持っていないということです。

このようにnew_listは__iter__メソッドしか持っていません。よって、new_listはイテレータではありません。

以上より、Pythonのリストオブジェクトは、イテレータそのものではないとわかりました。Pythonでは、リスト型以外にも辞書型や集合型などなどもイテレータではありません。

では、試しにnew_listのイテレータを作ってみましょう。今回はiter()関数を使って作ってみます(他にも方法はあります)。そして出来たイテレータがきちんと、__iter__()メソッドと__next__()メソッドを有しているか、dir関数を使って確かめてみます。次のコードを書きます。

iterator_of_new_list=iter(new_list)
print('__iter__' in dir(iterator_of_new_list))
print('__next__' in dir(iterator_of_new_list))

1行目でiter()関数を使ってnew_listのイテレータを作ります。2行目と3行目はそれぞれ両メソッドが含まれているかの確認です。

この確認の結果、両メソッドともに「True」が出力されます。つまり、作成されたイテレータであるiterator_of_new_listは、両メソッドとも持っているということになります。

それでは次にfor文とイテレーターとの関係を見ていきましょう。

Pythonのfor文の仕組み

Pythonのfor文は次のような書き方です。

for_stmt ::=  "for" target_list "in" expression_list ":" suite

for文については公式ドキュメントで次のようにその仕組が解説されています。

式リスト(expression_list)は一度だけ評価されます。その結果はイテラブルオブジェクトにならなければなりません。 expression_list の結果に対するイテレータが生成されます。 その後、イテレータが与えるそれぞれの要素に対して、イテレータから返された順に一度づつ、スイート(suite)が実行されます。

ちょっとわかりにくいかもしれませんが、簡単にかけば重要なことは次の2点です。

  • inの後の式から、イテレータが作られる
  • 作られたイテレータの中にある各要素に対して1回ずつ処理が実行される

forのinの後にリスト型のオブジェクトを書いた場合は、上で確認したようにリスト型のオブジェクトは、__iter__()メソッドを持っていますが、__next__()メソッドは持っていません。すなわち、イテレータではなかったのでした。

そして、__iter__()メソッドの機能については再確認となりますが、

オブジェクトの種類 機能
イテレータイテレータであるオブジェクトそのものを返す
それ意外
(ただし__iter__()メソッドを備えるもの)
オブジェクトのイテレータを新しく作成

です。

これらを踏まえて、もう一度今回の具体例のコードを見てみましょう。


  new_list=["A", "B", "C"]
  for i in new_list:
      print(i)

この処理の流れを簡単に順番に書いていくと、次のようになります。

for文のinの後に、new_listというリスト型オブジェクトがあります。これ自身はイテレータではないのでnew_listのイテレータが新しく作成される

そして作られたイテレータは__next__()メソッドを持っているため、1つずつ要素をfor文に渡す。

for文はそれを受け取り、1回ずつ処理を実行

という感じです。

イテラブルなオブジェクトとは?イテレータとの違いは?

上で見たきたように、何度も言いますが、for文のinの後のnew_listというリスト型オブジェクトそのものはイテレータではありません。しかし、それを元にしてイテレータが作成されます。

逆にいえば、イテレータを作ることが可能なオブジェクト(いいかえれば、最低限の機能として、__iter__()メソッドを備えているオブジェクト)が、イテラブルなオブジェクトだと考えることができます。

(イテラブルは英語「iterable」です。意味は「反復可能な」。これはiteratorとは違い、普通の英文でも使われる日常的な(?)単語です)

もちろん、イテレータそのものも__iter__()メソッドを持っているので、イテラブルなオブジェクトという扱いです。すなわち、イテラブルなオブジェクトの1種としてイテレータがあるということです。厳密にいえば、イテラブルなオブジェクトという言葉と、イテレータという言葉は別の意味・概念の用語です。

以上より、Pythonのfor文については、

for ~ in イテラブルなオブジェクト(ただしイテレータ自身もOK):
    処理

ということになります。

Pythonのイテレータとfor文の仕組み、そしてイテレータとイテラブルなオブジェクトとの違い
Pythonのイテレータとfor文の仕組み、そしてイテレータとイテラブルなオブジェクトとの違い

今回は具体例としてリスト型オブジェクト(new_list)を使いましたが、まさにリスト型オブジェクトはイテラブルなオブジェクトです(__iter__()メソッドを持っているから)。また同様に、辞書型や集合型(set型)オブジェクトも__iter__()メソッドを持っているのでイテラブルなオブジェクトなのです。

そういったオブジェクトがfor文でよく使われるのは、そういった理由?根拠?なのです。

自分でイテレータを作れる

さて、以上のようにイテレータとは、

  • __iter__()メソッド
  • __next__()メソッド

の2つを同時に持っているオブジェクトというものです。

乱暴にいえば、これら2つのメソッドさえ持っていればなんでもかんでもイテレータです。

したがって、これらのメソッドを定義した自作のイテレータを作ることが可能です。

やっぱりプログラミングは独学だとわかりにくいですよね、そこでスクールや動画による解説を利用しましょう!

Tech Academy

厚切りジェイソンのCMでおなじみのプログラミングスクール。自宅でオンライン受講OK。現役のプロが一人一人に専属メンターになってくれ、質問すればすぐに回答。転職保証あり

Udemy

世界最大級のオンライン学習動画サービス。AI・データサイエンスなど最先端のプログラミング講座からビジネススキル講座まで10万以上の講座から選び放題。講師に掲示板から直接に質問もできる。