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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

3114閲覧

yieldとreturnの違いと使い分けについて

sequelanonymous

総合スコア123

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

2クリップ

投稿2018/08/13 03:26

編集2018/08/13 03:39

以下、同一ファイルになります。
http requestのcurlコマンドで複数のユーザを送り、下記コードのexusersに入ります。
そこでfor文でDBにすでに存在しないかどうかをチェックするコードになります。

下記、origin_output関数内でなぜyieldでいけないかの理由が思いつきません。yieldは、一時的にメモリに値を保存してステータスを維持しながらfor文が処理されるという認識です。
しかし、そんなに重要な気がしていないのでどなかた、メリット及び使いわけについてアドバイスお願いできませんでしょうか ?

python

1def json_output(status, exuser, ac): 2 3 if status == 0: 4 list = {"exuser": exuser, "ac": ac} 5 r = {"code": 200, "body": list} 6 else status == 1: 7 r = {"code": 422, 8 "body": {"code": 422, "error": "Duplicated" + " "}} 9 return r 10 11 12def origin_output(exusers, cid): 13 14 allids = [] 15 db_ids = get_exids(cid) 16 for user in exusers: 17 ac = None 18 if user in ids: 19 status = 1 20 else: 21 status = 0 22 allids.append(user) 23 ac = insert_ac(cid, user) 24 yield json_output(status, user, ac)

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

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

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

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

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

yohhoy

2018/08/13 04:44 編集

「origin_output関数内でなぜyieldでいけないか」とはどのような意味でしょうか?yieldを使うのが望ましい設計か否かというニュアンスですか?
yohhoy

2018/08/13 09:08

yield(ジェネレータ)とするかreturn(通常関数)とするかは動作要件次第ですが、レビュー等で指摘されたということでしょうか?端的に回答するなら「全数列挙を遅延評価したいか?」に尽きます。
sequelanonymous

2018/08/13 09:12

指摘とかではなく、単純にyieldとreturnの使い分けを把握したいです。「全数列挙を遅延評価したいか?」の理由はなんでしょうか?どんな時に遅延評価すべきか否かが気になっています。yieldを使うと全数列挙を遅延評価できるのは知っています。
guest

回答2

0

ベストアンサー

リストを返す関数として設計した場合、呼んだ瞬間にDBが「うにゃーん」と総なめにされそうです。それを嫌ったのかも知れません(あまり深く検討していませんが)。


python

1for x in リストを返す関数(): 2 xを用いて何らかの処理 # これに取り掛かれるのは「リストを返す関数」の呼び出しが返ってから 3 4for x in ジェネレータ: 5 xを用いて何らかの処理 # 最初の1件が返ればとりあえず処理を始められる

これでトータルの処理時間は変わらないと推察されますが、「ぜんぶの情報は要らないので速く次に行ってくれ」という状況(breakが入るようなコード)とか、並行処理やI/Oが絡むような状況では有用でしょう。

投稿2018/08/13 15:47

編集2018/08/13 15:52
hayataka2049

総合スコア30933

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

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

0

何をしたいのかによりますが、yieldはジェネレーターを返しませんか?


ちょっとわかりやすい気がする無限ループ。

python

1def f(n): 2 c = 0 3 while True: 4 c += 1 5 yield c 6 if c > n: 7 c = 0 8 9if __name__ == '__main__': 10 n = 10 11 g = f(n) 12 while True: 13 print(next(g))

投稿2018/08/13 06:34

編集2018/08/13 16:08
mkgrei

総合スコア8560

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

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

sequelanonymous

2018/08/13 08:08

はい、それは知ってます。 別にyieldでもreturnでもこのコードではいいと思ってます。しかし、あえてyield じゃなきゃダメ理由、もしくは、yieldの方がいい理由が気になっています。
mkgrei

2018/08/13 13:44

遅延評価をすればメモリを温存できます。 速度はそれほど変わらないかも知れません。swapが発生しなければ。
sequelanonymous

2018/08/13 15:10

メモリが温存できるというメリットのみしかないのでしょうか?
mkgrei

2018/08/13 16:00

hayataka2049さんの回答とも重なるところがあるかも知れませんが、パイプラインなどの場合も有用です。 物理筐体をまたがった非同期並列処理などですね。 逐次処理は全てが終わる前から、次の処理に移れます。 極端な例だと無限ループを回す場合などです。 循環する数列に対して処理を行い続ける場合など、最初に配列を準備することができません。 配列でやろうとすると、一部準備して処理して次、みたいなロジックになってしまいます。 yieldを使うと少しだけすっきり組めます。 並列計算のスケジューラなども同様ですが、普通はキューを使うでしょうね。 ただこのような使い方は一概にうまくいくとは言えず、メモリが温存できる、というようなはっきりとした利点としてはあげにくいかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問