Pythonの技法:ジェネレータを用いた遅延リストの構築
翻訳校正:原井彰弘
プログラムがやる気を出しすぎて、必要のない処理やあなたが実行して欲しくないと思っている処理まで行ってしまうのはよくあることである。プログラムにはもっと怠け者であって欲しいのだ。そこで、ジェネレータの出番である。Pythonのジェネレータを用いると、いつどれだけ処理を行って欲しいかを正確に指定することが可能となる。
既にリストの内包表記というものを紹介した。リストの内包表記を用いれば、リストの内容をより自然な方法で表現することが可能なのであった。本稿では、そのリストの内包表記と「いとこ」の関係にあるもの「ジェネレータ」を紹介しよう。ジェネレータを利用すると、シーケンスの各要素を一つずつ構築することが可能となるため、あなたが必要とするだけの処理が行われるようになるのである。
これは遅延評価と呼ばれ、プログラムが値を実際に必要とするまで、特定の値の計算を遅らせるしくみである。遅延評価を利用すれば、まったく使用されない値を計算してしまうことがなくなってパフォーマンスが向上するので、遅延評価はプログラミングのさまざまな場面で活用できる。HaskellやMirandaのような言語では、遅延評価がデフォルトの振る舞いになっているほどだ。またSchemeやOCaml、Pythonでも、特別な構文を用いれば遅延評価を行える。Pythonの場合は、ジェネレータでこれを実現する。
ジェネレータを利用して関数を記述すると、ただ単に結果を返すだけではなく、実行中に「一時停止」を行って次に呼び出されたときにはそこから実行を再開することが可能になる。ジェネレータを記述するのに専用の複雑な構文は必要ない。途中の値を返したいときにyield文を用いるだけでよいのである。これは例を用いて説明するのが手っ取り早い。次のコードを見て欲しい。
>>> def generator1(): ... yield "first" ... yield "second" ... yield "third" ... >>> gen = generator1() >>> gen >>> gen.next() 'first' >>> gen.next() 'second' >>> gen.next() 'third' >>> gen.next() Traceback (most recent call last): File "", line 1, in ? StopIteration >>>
この例ではまず最初に、「first」「second」「third」という3つの値を生み出すジェネレータ「generator1」を定義している。この関数は、新しいジェネレータのオブジェクト(gen)が作成されたときに実行が開始される。そして、ジェネレータのnextメソッドが呼び出されるたびに、次のyieldに達するまで実行が続けられるのである。最後に、ジェネレータの実行がブロックの最後かreturn文にたどり着くと、StopIteration例外がスローされる。
- 1人の推薦記事
- 0人がクリップ
-
ソーシャルブックマーク(-)
- トラックバック(0)
- 4日前のトップ記事
- 5日前
- 6日前
- 7日前
- 8日前
- ホワイトペーパー
- 話題のタグ
MS運営のオープンソース開発プロジェクト支援サイト「CodePlex」を探検する(2)
Snow LeopardではNTFSをサポート--その源流を訪ねる(1)
フォトレポート:「Windows Server 2008 R2」--あまり知られていない有用な機能10選
マイクロソフト、「Office 2010」ベータ版を開発者向けにリリース
大丈夫?あなたの会社のセキュリティ対策
電力に"ふた"をする独自の省エネ機能とは!?
高まるiSCSIストレージへの注目度
【最終警告】パンデミック対策特集
―エン・ジャパン厳選求人☆毎週更新―
企業ITシステムの企画、構築、運用のイロハ
100万円で実現!中小企業の情報漏えい対策