質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

481閲覧

pythonのジェネレータ関数 基礎的な使い方がわかりません

nanata_umu

総合スコア1

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/11/03 14:26

編集2020/11/04 12:43

pythonのジェネレータの使い方を知りたいです

def gen(maxnum): base=0 i=0 while i < maxnum: o=(yield base+i) if o is not None: base = o else: i+=1 g=gen(10) #1 print(next(g)) #2 print(next(g)) g.send(10) #3 print(next(g)) #4 print(next(g)) g.send(0) #5 print(next(g)) #6 print(next(g)) #7 print(next(g))

実行結果

0 1 12 13 4 5 6

試したこと

pythonの絵本から持ってきたコードです

print(next(g))がどのように処理され値が呼び出されるのかいまいちわかりません。

def gen(maxnum): base = 0 i = 0 while i < maxnum: o=(yield base + i) if o is not None: base = o else: i += 1

私なりには #1 print(next(g)) に呼び出しされ g=gen(10) が処理され上記defの関数の式が開始されて、
gen(maxnum)のところに(10)が代入され
while i < maxnum(10):となり、while文が処理されると考えていいのでしょうか?

while i < maxnum: o=(yield base + i) if o is not None: base = o else: i += 1

ここで処理では o=(yield base + i) で中断し呼び出し元にに戻ると記載されているのですが
o= base + iが戻り値になるのですか?

if o is not None: base = o else: i += 1

次に#2 print(next(g))が上記のコードから再開されるのでしょうか?
if o is not None: の意味はわかるのですがo変数がNoneになる場合とならない場合の処理を教えてください。

g.send(10)

send()メゾットはどこに値を送るのでしょうか?

補足情報(FW/ツールのバージョンなど)

情報不足ですみません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2020/11/04 01:09

書いてあるコードはなんですか? 「こんな感じだと思ったけど動かないコード」ですか? そうであれば「どう動くことを期待したコードか?」「どのように動かないのか? エラーになるのか、意図しない動作になるのか?」の説明が必要です。 「自分には意味は分からないけれどどこかから拾ってきた動くコード」ですか? そうであれば「どこに書かれているどういうコードなのか?」「実際に自分で動かしてみたのか? どういう結果になったのか?」の説明が必要です。 その上で「いったいどこが疑問点なのか?」を書いてください。 それと、今のままではコードが読めません。 https://teratail.com/help/question-tips#questionTips3-5-1 を参考に編集からコードを選択して <code> ボタンでコードの前後行に ``` をいれて読めるようにしてください。
nanata_umu

2020/11/04 12:44

アドバイスありがとうございます。 情報が足りないようであれば随時追加します。 説明足らずで申し訳ございません。
guest

回答2

0

ベストアンサー

こんな感じです。

ジェネレータも普通の関数ど同様に処理が行なわれます。関数はreturnで値を返すと、その関数は終ってしまいますが、yieldで値を返すと、returnと違っても関数が終了せず生きていて、nextを呼び出すことでで続きができるのです。
また、呼び出し側がジェネレータのsend()で、yieldの返り値を渡すことができます。

処理を追うとこんな感じです。

g=gen(0) でジェネレータが生成されます。通常の関数とちがって、ここでは実行結果の返り値ではなく、生成されたジェネレータがgに入ります。

next(g) で、yieldまで実行され、base+i が呼び出し元に返ります。
最初は base=0 で i=0なので、0が返ります。
さらにnext(g)が呼ばれると、yieldの次の行から再開します。この時、yieldの返り値は、send()を呼んでいないので、None におり、if文はelse側が実行され、ループが回って、yield base+i (base=0, i=1) で 1 が返ります。

g.send(10) を実行すると、関数内のyieldの返り値にsendの結果が渡されます。 ということで o に 10 が入ることになります。
ここで next(g) を呼ぶと、if文 はoの値がNoneではないので、てbaseの値がo すなわち sendで渡された10に書き換えます。
yield base+i は base=10 で i=2 なので、12を返します。

以降はご自分で追いかけてみてください。

投稿2020/11/04 13:47

TakaiY

総合スコア12765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanata_umu

2020/11/05 11:23

丁寧にありがとうございます。解説してもらった通りに解読していったら実行結果と同じになりました。 yield,next(),send()の使い方についてすっきりできました!
guest

0

gen(maxnum)のところに(10)が代入され
while i < maxnum(10):となり、while文が処理されると考えていいのでしょうか?

gen(maxnum)の maxnum に 10 が代入され
while i < 10:となり、while文が処理されます。

ここで処理では o=(yield base + i) で中断し呼び出し元にに戻ると記載されているのですが
o= base + iが戻り値になるのですか?

違います。
base + i が戻り値になります。

次に#2 print(next(g))が上記のコードから再開されるのでしょうか?

違います。
o=(None or send() 値) から再開されます。

if o is not None: の意味はわかるのですがo変数がNoneになる場合とならない場合の処理を教えてください。

o変数が None になる場合
_ next(g) により yield が値を返した後 next(g) を実行した場合
o変数が None ならない場合
_ next(g) により yield が値を返した後 g.send(10) を実行した場合

send()メゾットはどこに値を送るのでしょうか?

yield base + i の式の値になります。

投稿2020/11/04 15:02

lehshell

総合スコア1147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問