IT

Pythonのイテレータとジェネレーター

今回はPythonのコードを書く上での基本となる、イテレータとジェネレーターについて短いですが、紹介します。

特徴

ここではpythonの中でも押さえておきたいイテレータとジェネレーターの特徴について紹介します。

・イテレータとは、データを走査していくときに使う、ポインタ的な役割をもったオブジェクト
・ジェネレーターとは、イテレータをつくるための概念みたいなもの
・イテレータは関数内にyield文を用意して戻り値を指定する。
・イテレータはnext関数でyield文の戻り値を取り出す。
・イテレータはsend関数で値を渡すこともできる

イテレータ

前回までに何度がでてきたこの『イテレータ』ですが、「たくさんのデータの中からデータを走査していく際に使う、ポインタ的な役割をもったオブジェクト」です。全てのデータをメモリ上に一度に出すとリソースを圧迫することから、必要な時に値を出すためにできた概念だと思います。イテレータの作成には『iter(イテレータ)』を使い、走査するために取り出すには『.next()』を使います。(python3からはnext(イテレータ)で取り出します)一般的には後述するジェネレーターを使って作成します。また、全ての走査が終わり、さらにデータを取り出そうとすると「StopIteration」エラーが発生します。


>>> _iter = iter(['A','B','C'])
>>> for i in _iter:
...     print(i)
...
A
B
C

for文で取り出す場合は、next関数を使わずともよいです。

ジェネレーター

ジェネレーター』とは広義のイテレータです。関数みたいなもので、特徴はその関数内のローカル変数を保持したままでイテレータがnext関数などで次の値を取り出すまでは評価を中断できます。極端な言い方、関数の処理を途中でとめられるのです。そのためには関数内に『yield 戻り値』文を使います。このyield文を用いることによってイテレータを作成することができます。yield文の戻り値は、イテレータを進めることによって順次評価されます。


>>> def _iter():
...     yield 1
...     yield 2
...     yield 3
...
>>> for i in _iter():
...     print(i)
...
1
2
3

もう一つ例として偶数の値を出力するイテレータを作成します。


# encoding:utf-8
def get_evennum():
    num = 1
    while True:
        if num%2 == 0:
            yield num
        else:
            pass
        num += 1
#偶数を返すジェネレータを作成
evennum = get_evennum()
for i in range(10):
    print(evennum.next())
[結果]
2
4
6
8
10
12
14
16
18
20

ジェネレーターは戻り値を出力するだけでなく、値を受け取ることができます。その時は『.send(受け取り値)』を使います。send関数はnext関数を一度呼ばないと使えないことに注意してください。


# encoding:utf-8
def func():
    #1の戻り値を返し、さらに受け取った値をrcvに格納する
    rcv = (yield 1)
    print('rcv:{0}'.format(rcv))
test=func()
try:
    test.next()
    test.send(10)
except StopIteration:
    pass
[結果]
rcv:10

まとめ

ここにタイトルを入力

・イテレータとは、データを走査していくときに使う、ポインタ的な役割をもったオブジェクト
・ジェネレーターとは、イテレータをつくるための概念みたいなもの
・next関数でイテレータのyield文の戻り値を取り出し、send文は値をイテレータに渡す

以上。