iterとは?
Pythonのiter関数は、オブジェクトからイテレータを作成するための組み込み関数です。
イテレータとは、トランプの山札からカードを1枚ずつ引くように、要素を順番に一つずつ取り出せる仕組みを持つオブジェクトを指します。
私たちが普段for文を使ってリストやタプルの要素を順番に処理できるのは、Pythonが内部でiter関数を使ってイテレータを取得し、要素を一つずつ取り出しているためです。
iter関数を使うと、リストや辞書はもちろん、自作のクラスなど、さまざまなオブジェクトをイテレータに変換できます。
iterの特徴
- リストやタプルなど反復可能なオブジェクトをイテレータに変換する
- for文が内部で利用する反復処理の仕組みを利用できる
- 要素を一つずつ取り出すためメモリ効率が良い
- 大規模なデータやファイルを少しずつ処理するのに適している
【関連】
Pythonをもっと詳しく学ぶならpaizaラーニング
基本構文
iter関数(イテレータかんすう)には、主に2つの使い方があります。
最も基本的な形式であるiter(iterable)は、リストや文字列といった反復可能なオブジェクト(イテラブル)からイテレータを作成します。
もう一つの形式であるiter(callable, sentinel)は、関数(callable)と、処理を停止するための目印となる番兵値(sentinel)を指定してイテレータを生成します。
まずは、基本的なiter(iterable)の使い方を見ていきましょう。
出力結果
1
2
3この例では、iter関数でリストからイテレータを作成しています。next関数は、イテレータから要素を一つずつ順番に取り出す関数です。iteratorに対してnext関数を呼び出すたびに、リストの次の要素である1、2、3が順番に取り出されて出力されます。
もし、リストの全ての要素を取り出した後で、さらにnext(iterator)を呼び出すと、取り出す要素がもうないためStopIterationという例外が発生します。for文は、内部でこの仕組みを使ってループの終わりを判定しています。
次に、iter関数で作成したイテレータをfor文で処理する例を見ていきましょう。文字列も反復可能なオブジェクトのため、iter関数を使用できます。
出力結果
ネ
コこの例では、文字列"ネコ"からイテレータを作成しています。for文は、内部でイテレータから要素がなくなるまで(StopIteration例外が発生するまで)一つずつ要素を取り出して処理を繰り返します。そのため、文字列の各文字である「ネ」と「コ」が順番に出力されます。
実用例
ここからは、iter関数の具体的な活用方法を紹介します。実際のプログラミングでよく使われるパターンを中心に、8つのサンプルコードを用意しました。各例では、iter関数の特徴を活かした効率的な処理方法を学べます。これらの例を通して、日常的なプログラミング作業でiter関数を活用する方法を理解していきましょう。
リストからイテレータを作成
for文を使わずに、while文とnext関数、StopIteration例外(例外処理)を使ってリストの要素を順番に処理する例です。
イテレータは必要な時に必要な分だけ要素を一つずつ取り出すため、メモリ効率の良い処理の基本となります。
出力結果
イヌ
ネコ
ウサギこの例では、while Trueの無限ループの中でnext(animal_iter)を呼び出し、要素を一つずつ取り出しています。
try...except構文を使い、イテレータが空になってStopIteration例外が発生したらbreak文でループを終了します。for文は、内部的にこのような処理を自動で行っています。これが巨大なファイルやデータセットであっても、イテレータを使えば全体を一度にメモリに読み込むことなく(メモリを圧迫せずに)処理できます。
辞書のキーをイテレータで処理
辞書のキーを効率的に処理する例です。keys()メソッドが返すオブジェクトからイテレータを作成し、for文で処理します。大量のデータを扱う際に特に有効です。
出力結果
タマは3歳です
ポチは5歳です
シロは2歳ですこの例では、pet_ages.keys()で辞書のキーを一覧を取得し、iter関数でイテレータkey_iterを作成しています。for文でkey_iterを回すことで、キー("タマ", "ポチ", "シロ")を一つずつ取り出し、f文字列(フォーマット済み文字列リテラル)を使って対応する値(年齢)とともに出力しています。
ファイル読み込みでのイテレータ活用
テキストファイルの内容を行ごとに処理する例です。ファイル読み込みを模して、リストからイテレータを返す関数を定義しています。
出力結果
['ライオン', '肉食']
['パンダ', '草食']
['クマ', '雑食']この例では、read_animal_data関数が内部で作成したリストのイテレータを返しています。animal_dataにはイテレータが格納され、for文で要素を一つずつ取り出します。line.split(":")によって、各文字列がコロン:で分割され、リストとして出力されています。
関数と番兵値を使ったイテレータ生成
基本構文で紹介したiter関数のもう一つの使い方であるiter(callable, sentinel)の例です。特定の目印となる値(番兵値)が現れるまで、繰り返し関数を実行し続けたい場合に使われます。
例えば、ネットワークやファイルからデータを少しずつ読み込む際、データの終わりを示す特定の値(例えば空の文字列 '' や None)が返されるまで、読み取り関数を呼び出し続ける、といった処理の実装に役立ちます。
出力結果
---イテレータ処理開始---
(関数が呼び出され、'キリン' を返しました)
イテレータが返した値: キリン
(関数が呼び出され、'ゾウ' を返しました)
イテレータが返した値: ゾウ
(関数が呼び出され、'サル' を返しました)
---イテレータ処理停止('サル' が検出されました)---この例は、クロージャ(create_data_source)で定義されたデータ取得関数(get_data_func)を、番兵値"サル"を指定したiter関数と組み合わせ、"サル"が返される直前までデータを順に取り出す処理を実装しています。whileループの中でnext(animal_iter)が呼び出されると、iter関数は内部でget_data_funcを呼び出します。
1回目はget_data_funcが"キリン"を返します。"キリン"は番兵値"サル"と異なるため、next関数は"キリン"を返します。2回目はget_data_funcが"ゾウ"を返します。"ゾウ"も番兵値と異なるため、next関数は"ゾウ"を返します。3回目はget_data_funcが"サル"を返します。"サル"は指定された番兵値と一致するため、next関数は"サル"を返さずに、StopIteration例外を発生させます。
try...exceptでStopIterationをキャッチし、break文によってループが停止します。そのため、"サル"(番兵値)自体や、それ以降の"ライオン"は出力されません。
無限イテレータの作成
yieldキーワードを使って、データを繰り返し生成し続けるジェネレータ関数を定義する例です。このような関数を使うと、特定のパターンに従って無限に値を返し続けるイテレータを作成できます。
出力結果
トラ
ヒョウ
チーター
トラ
ヒョウこの例では、infinite_animals関数が無限ループ(while True)の中でyieldを使い、動物のリストを循環しながら値を返し続けます。animal_genはジェネレータ(イテレータの一種)です。enumerate関数でインデックスiを取得し、iが5になったらbreak文でループを停止させ、無限ループに陥るのを防いでいます。
条件付きイテレータの実装
ジェネレータ関数を使って、特定の条件を満たす要素だけを返す(フィルタリングする)イテレータを作成する例です。
出力結果
['ゾウ', 'キリン', 'クジラ']この例では、filter_large_animals関数がall_animalsリストを反復処理します。animalがlarge_animalsリストに含まれている場合のみ、yieldでその要素を返します。
filter_large_animalsを呼び出すとジェネレータが返されます。list関数でイテレータの全要素を取り出し、リストとして出力しています。
複数データ源の統合処理
複数のデータソースからイテレータを作成し、統合して処理する例です。異なる形式のデータを統一的に扱えます。
出力結果
動物: ウマ
動物: ウシ
動物: イルカ
動物: シャチこの例では、yield fromを活用したジェネレータ関数combine_iteratorsを定義し、複数のイテラブル(land_animals と sea_animals のリスト)を連結して順次処理する単一のイテレータall_animals_iterを生成しています。
yield fromは、指定されたイテラブル(この場合は iter(iterable)によって得られる各リストのイテレータ)の全要素を一つずつ返します。結果として、all_animals_iterは両方のリストの要素を順番にすべて返すイテレータとなります。
データ変換パイプライン
イテレータを使って、データを段階的に変換する処理(パイプライン)を実装する例です。処理の各段階を明確に分離できます。
出力結果
['かわいいコアラ', 'かわいいパンダ', 'かわいいペンギン']この例では、transform_animals関数がoriginal_animalsリストを受け取り、イテレータに変換しています。for文で要素を一つずつ取り出し、f-stringで「かわいい」を付け加えた新しい文字列をyieldで返します。transformedはジェネレータとなり、list()関数で全要素を取り出すと、変換後の文字列がリストになって出力されます。
まとめ
Pythonのiter関数は、効率的な反復処理を実現する重要な関数です。この記事では、基本的な使い方からメモリ効率を高める仕組みまで解説しました。
iter関数が活躍する場面
- 大量のデータを少しずつ処理してメモリを節約したいとき
- ファイルを行単位で読み込むとき
- 自作のクラスでfor文を使えるようにしたいとき
iter関数を用いる上で、押さえておきたいポイントを覚えておきましょう。
重要なポイント
- イテレータはメモリ効率が良く大量データに適している
- 要素を一つずつ順番に取り出すことができる
- ジェネレータ関数(yield)と組み合わせて活用できる
初めてPythonを学ぶ方も、この記事で紹介したiter関数を実際に書いて、基本的な使い方を試してみてください。
メモリ効率の良いコードは、実際の開発で非常に役立ちます。ぜひiter関数をマスターして、より大規模なデータを扱える実用的なプログラムを作成できるようになりましょう。