無名関数lambdaを使うべき時がわかりません。
手軽にメソッドが作れる、とサイトに書いてありましたが
ならdef ~~ のようなメソッドを作らず、
全てlambdaを使ってメソッドを書けばいいのでは、と思ってしまいますが
そんな書き方しないですよね?
無名関数lambdaを使うべき時はどのような時なのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
もし、関数型プログラミングを知っているのであれば、ラムダ式がなぜ便利なのか、なぜ必要なのかがよくわかるでしょう。LISPやHaskellをさわったことがあれば、答えは既に知っているはずです。たとえ関数型プログラミングを知らなくても、代わりにRubyのブロックを知っているのであれば、そう、あれはまるでラムダ式を与えているような物であると言うことに気付いていれば、やはり答えを既に知っているはずです。
さて、私達が興味があるのはPythonです。だから、上のことは忘れてPythonの話をします。
Pythonでラムダ式が必要になるとき、それは、高階関数が必要になるときです。高階関数とは関数を引数にする関数、または、関数を戻り値にする関数です。ラムダ式を使うのは前者です。
関数を引数にする関数、そんな物なんてあったかなと思ったかもしれません。Python3でよく使われる(話題に出る)と言われているのは、filter()
、map()
、max()
、min()
、sorted()
、functools.reduce()
、tertools.accumulate()
あたりでしょう。特にfilter()
、map()
、functools.reduce()
はよく話題に出ると思います。が、別に使う必要はありません。むしろ、使うべきではないとPythonのドキュメントは言っています。
例題として、与えられた数列x
について、3の倍数を除外し、それぞれを2乗して、それら全てをビットXORした数を求める事とします。
Python
1import functools 2x = [3, 1, 9, 4, 5, 23, 31, 93, 83, 72, 52, 44, 0, 6, 48] 3r = functools.reduce(lambda a, b: a ^ b, map(lambda i: i * i, filter(lambda j: j % 3 != 0, x)), 0) 4print(r)
リスト内包表記と普通のforを使えば次のように書けます。
Python
1x = [3, 1, 9, 4, 5, 23, 31, 93, 83, 72, 52, 44, 0, 6, 48] 2r = 0 3for i in [j * j for j in x if j % 3 != 0]: 4 r ^= i 5print(r)
どっちの方がわかりやすいかというと、断然後者でしょう。つまり、ラムダ式は無理に使う必要は無く、むしろ、使わない方が簡単でわかりやすい場合が多いと言えます。
話は戻って最初のHaskellとRubyではどうなるかを見ましょう。
Haskell
1import Data.Bits 2x :: [Integer] 3x = [3, 1, 9, 4, 5, 23, 31, 93, 83, 72, 52, 44, 0, 6, 48] 4r = foldr xor 0 $ map (\i -> i * i) $ filter (\j -> mod j 3 /= 0) x 5main = print r
Ruby
1x = [3, 1, 9, 4, 5, 23, 31, 93, 83, 72, 52, 44, 0, 6, 48] 2r = x.select { |i| i % 3 != 0 }.map { |j| j * j }.inject(0, :^) 3puts r
Pythonに比べれば使いやすいようにできています。たぶん、これは言語文化の違いかも知れません。※
※ Haskellはリスト内包表記も書けるので、上のコードが一番良い書き方とは言えません。
Haskell
1import Data.Bits 2x :: [Integer] 3x = [3, 1, 9, 4, 5, 23, 31, 93, 83, 72, 52, 44, 0, 6, 48] 4r = foldr xor 0 [i * i | i <- x, mod i 3 /= 0] 5main = print r
投稿2017/04/24 14:43
編集2017/04/24 14:46総合スコア21733
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。