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

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

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

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

Q&A

解決済

3回答

170閲覧

python3のジェネレーターについて

pokkutter

総合スコア201

Python 3.x

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

0グッド

1クリップ

投稿2018/02/24 01:18

以下の関数をpython3でジェネレーターに変更したいです。

def mufunc(start, end, multiple, non_multiple):
print(*filter(lambda i: i % multiple == 0 != i % non_multiple, range(start, end + 1)))

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

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

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

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

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

guest

回答3

0

python

1def mufunc(start, end, multiple, non_multiple): 2 yield from filter(lambda i: i % multiple == 0 != i % non_multiple, range(start, end + 1))

投稿2018/02/24 01:32

YouheiSakurai

総合スコア6142

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

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

0

ベストアンサー

補足の補足という意味の分からないことをしますが、KSwordOfHasteさんがいろいろ調べたことに対して。
yield fromを使うと、yield fromを複数並べることが出来るようになるりますね。

Python

1def mufunc(start, end, multiple, non_multiple): 2 for i in range(2): 3 yield from filter(lambda i: i % multiple == 0 != i % non_multiple, 4 # 上のfor文は次と2行と同等 5 # yield from filter(lambda i: i % multiple == 0 != i % non_multiple, 6 # yield from filter(lambda i: i % multiple == 0 != i % non_multiple, 7 8 9range(start, end + 1))

yieldやyield fromはもっと複雑な使い方も出来るのですが、あんまりおもしろい例を知らないので、ひとまずreturn filter(xxx)との違いの補足までに。

投稿2018/02/24 04:56

編集2018/02/24 05:24
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

KSwordOfHaste

2018/02/24 05:52

generatorの柔軟な点は規則性がない(不連続な)列や個々の要素を自由に一つの列として合成できる点にあると思います。 def concat(*iterators):  for iterator in iterators:   yield from iterator こんなのもすっきり書けるというのが便利ですよね。ちなみに他の言語でもyield from的な構文あると思います。Pythonにもあるだろうと気づいてしかるべきでした。アハハ(汗
guest

0

質問内容の本質には関係なさそうな話ですが・・・

YouheiSakuraiさんの回答をみて「yield from」とかけることを知り、ジェネレーターの書き方を調べているうちに結構色々書き方があることがわかったので、速度を簡単に比べてみました。

Python

1import time, math 2 3# 様々な列を生成できるのがgeneratorの基本でしょうから 4# yield fromを知らなかったのは損してました 5 6def f1(start, end, multiple, non_multiple): 7 yield from filter(lambda i: i % multiple == 0 != i % non_multiple, 8 range(start, end + 1)) 9 10# 素朴な例? 11 12def f2(start, end, multiple, non_multiple): 13 for i in range(start, end + 1): 14 if i % multiple == 0 != i % non_multiple: 15 yield i 16 17# 内包表記と同じようにジェネレーターを書けるということを初めて知りました! 18 19def f3(start, end, multiple, non_multiple): 20 return (i for i in range(start, end + 1) 21 if i % multiple == 0 != i % non_multiple) 22 23# これはgeneratorではないかも知れないが使い勝手は同じだろうと思ったので比較対象に入れた 24 25def f4(start, end, multiple, non_multiple): 26 return filter(lambda i: i % multiple == 0 != i % non_multiple, 27 range(start, end + 1)) 28 29start = 0 30end = 1000000 31multiple = 2 32non_multiple = 3 33 34for f in [f1, f2, f3, f4, f1, f2, f3, f4]: 35 s1 = 0 36 s2 = 0 37 n = 20 38 for i in range(n): 39 t = time.time() 40 sum(f(start, end, multiple, non_multiple)) 41 t = time.time() - t 42 s1 += t 43 s2 += t * t 44 μ = s1 / n 45 σ = math.sqrt(s2 / n - μ * μ) 46 print("{}: {:.6f} {:.6f}".format(f.__name__, μ, σ))

各々sumを20回実行し平均、標準偏差を印字しています。実行時間がかなり変動するので2セットやってます。

f1: 0.280532 0.034435
f2: 0.147682 0.007799
f3: 0.147200 0.009094
f4: 0.195394 0.007899
f1: 0.214874 0.006771
f2: 0.146917 0.007629
f3: 0.149237 0.009201
f4: 0.198542 0.007140
(Windows 10 64bit, Python 3.6.0)

測ったくせしてなんですが、非常に些細な差なので「わかりやすい」と感じるものを選ぶのがやはりいいのかなと思いました。


ちなみにfilterで機能が達成できているのですから、それを**わざわざgeneratorにする必要性はない気がしました。**どうなのでしょう?

投稿2018/02/24 03:54

KSwordOfHaste

総合スコア18394

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

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

YouheiSakurai

2018/02/24 04:04

f4ではなくf1にした理由は、f1の方がなんとなく見た目がジェネレーターっぽいからだと思います。正直、全然深くは考えていませんでした。
KSwordOfHaste

2018/02/24 04:20 編集

generatorでyieldとyield fromを使い分けてさまざまな列を柔軟に生成できるんだな!と言う点に気づくことができてYouheiSakuraiさんの回答で「これはよいことを知った」と自分は思いました。
KSwordOfHaste

2018/02/24 04:37

dkato0077さん 補足ありがとうございました。なるほど書いてありますね! 今まで内包表記と同じノリでgeneratorが書けるといったことも知らなかったので本件でよい勉強させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問