読者です 読者をやめる 読者になる 読者になる

pythonのお勉強(ジェネレーター関数)

ラズパイINDEX http://SNS.jp/view_diary.pl?id=1957925373&owner_id=2637459

〜〜〜〜〜〜〜〜〜〜

ジェネレーター関数

〜〜〜〜〜〜〜〜〜〜

イテレート可能なオブジェクトを関数を使って定義する。これをジェネレーター関数という

ジェネレーター関数は値を戻すreturn文の代わりにyield文を使う。

yield文はイテレートなので順に値を返すが、値を返したら関数は中断し一時停止する。

そしてnext()関数が呼ばれると実行を再開する

def name(str):

for word in str.upper():

yield word

pri = name(yaruo)

print(next(pri))

print(next(pri))

print(next(pri))

print(next(pri))

print(next(pri))

print(next(pri))

結果

Y

A

R

U

O

Traceback (most recent call last):

print(next(pri))

StopIteration

関数nameが呼び出され値であるyaruoが関数の仮引数strに入る

str.upper()で大文字化された値がwordに入って順にyieldで値を返される返された値はpriに代入される。

print(next(pri))でnext()関数が呼び出されてるのでyield文が再開され一文字づつprintされる

6番目のprint文は戻す値がない(yaruoは5文字の為)のでエラーが出る

尚、ジェネレーターオブジェクトはイテレート可能なのでfor文で使える

def name(str):

for word in str.upper():

yield word

moji = name(yaruo)

for pri in moji:

print(pri, end=)

結果

YARUO

〜〜〜

例題

〜〜〜

ジェネレーター関数を使った例題

重複のない整数の乱数を生成する

import random

def rand_num(num):

randoms =

while True:

ransuu = random.randrange(num+1)

if ransuu not in randoms:

randoms.append(ransuu)

yield ransuu

elif len(randoms) == (num+1):

break

入力された数字分の乱数を順に作成

作成された数字はリストに入れつつ値を返す

リストの中身が入力された数字+1になったら

すべての表示が終わったことなので関数を抜ける

while True:

try:

inp_num = int(input(u数字を入れてください ))

break

except:

print(u数字を入れてください)

continue

make_num = rand_num(inp_num)

for pri_num in make_num:

print(pri_num)

入力と出力

数字を入れてください 10

3

8

2

9

7

4

1

10

6

5

0

〜〜〜〜〜〜〜〜〜〜

ジェネレーター式

〜〜〜〜〜〜〜〜〜〜

lambdaのようにシンプルな処理はdefで関数定義せずにジェネレーター式という書式で書ける

str = yaruo

word = (wd for wd in str.upper())

for prwd in word:

print(prwd,end=)

YARUO

リストの内包表記に似ているがではなく()になっている。

実は

上記の文はリストを使っても同じ結果が出る

str = yaruo

word = [wd for wd in str.upper()]

for prwd in word:

print(prwd,end=)

結果

YARUO

2つの差はメモリーの消費量でリストの場合はリストの要素を全部生成してから処理を行うのに対しジェネレーターの場合は最初にも書いたように要求された時点(for文であればループの度、後next()関数など)で値を返すので膨大な量を処理する場合はジェネレーターのほうが有利になる

後は見通しの良さとかとの兼ね合い。

word=(wd for wd in str.upper())    #呼び出されたから返すよ

for prwd in word:           #呼び出すよ

word=[wd for wd in str.upper()]    #全部リストに入れるよ

for prwd in word:           #入れたのを変数に入れるよ

こんな感じ?