以下の関数をpython3でジェネレーターに変更したいです。
def mufunc(start, end, multiple, non_multiple):
print(*filter(lambda i: i % multiple == 0 != i % non_multiple, range(start, end + 1)))
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア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
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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
総合スコア18394
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/24 04:04
2018/02/24 04:20 編集
退会済みユーザー
2018/02/24 04:29
2018/02/24 04:37
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。