ジェネレータ

今回はジェネレータについて学習。
まずはジェネレータって何なのかというところから。
ジェネレータは関数の一種らしい。普通の関数はすべての処理が終わってから
return文で結果を返すけど、ジェネレータ関数は関数を動かしつつyield文で
何度も結果を返せるらしい。

ジェネレータ関数を呼び出すとイテレータオブジェクトが返るみたい。
for文はイテレータオブジェクトを伴ってループ処理を行うから、ジェネレータ関数を
使ってループ処理ができるらしい。

ジェネレータ関数の定義には通常の関数と同様にdef文を使うみたいで、引数を渡すことも
できるみたい。

通常の関数と異なるのは内部でyield文を使って値を返す点で、yield文とreturn文を1つの関数
で使うことはできないらしい。

いまいちよく分からないので例を探すとhttp://builder.japan.zdnet.com/news/story/0,3800079086,20365025,00.htm
にわかりやすい例があった。

>>> def generator1():
...     yield "first"
...     yield "second"
...     yield "third"
...
>>> gen = generator1()
>>> gen
<generator object at 0x00D5EE18>
>>> gen.next()
'first'
>>> gen.next()
'second'
>>> gen.next()
'third'
>>> gen.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

まずは定義の部分。returnの代わりにyieldで戻り値を3つ設定している。
そして定義した関数自体はジェネレータオブジェクトを返している。
それでジェネレータオブジェクトにnextメソッドを使うとyield文で設定した
戻り値を順に返してくるわけか。
つまりyield文で設定した戻り値を持つイテレータオブジェクトを呼び出している
感じなのか。

なのでforループに添えるシークエンスと同様にジェネレータを使えることに
なるみたい。

>>> def generator2():
...     yield "A"
...     yield "B"
...     yield "C"
...
>>> for i in generator2():
...     print i
...
A
B
C

ジェネレータ関数の定義の中でfor文を使ってyield文を繰り返すようにすれば
その回数分だけ戻り値を設定できるみたい。

>>> def generator3():
...     for y in range(1, 5):
...         yield y
...
>>> for i in generator3():
...     print i
...
1
2
3
4

ジェネレータ関数に引数を渡す例がhttp://www.geocities.jp/m_hiroi/light/python04.htmlにあったので
引用させていただくと、

>>> def generator4(start, end, step):
...     n = start
...     while n < end:
...         yield n
...         n += step
...
>>> for i in generator4(1, 12, 2):
...     print i
...
1
3
5
7
9
11

のような感じになるみたい。

概要は理解できたけど、より具体的にどんな場合に使うと効果的なのか
もう少し勉強が必要かも。