まとめながら理解してみた。
Q. lambda 関数とdef ステートメントの関係は? 両者を比較してください。
lambda と def は、どちらも関数オブジェクトを作ることができる、という点では共通しています。ただし、lambda は式なので、def ステートメントとは違い、文法的にdefステートメントが使用できない箇所でも使えます。たとえば、リストのリテラル、関数の呼び出しコードなどの中でも使えるのです。lambda は必ず使わなくてはならない、というものではありません。lambda と同等のコードは、必ずdef を使って書くことができるからです。ただ、def を使った場合、関数には最初からすべて名前がある、ということになります。lambda は、特定の場所だけで使われ、他に応用される可能性の低い、簡単な関数を作る場合に便利です。lambda で得られる戻り値は1つに限定されています。ステートメントのブロックには対応できないので、大規模な関数の作成には向きません。
by はじめてのPython 第3版 pp.405
で、結局使いどころはどこなの?という疑問。
具体的にいくつか試してみた。
、、、が、たぶん例が良くない。
せっかくの無名関数なのに、、、
>>> func = lambda a,b,c:a+b+c >>> func(2,3,4) 9
>>> def func(a,b,c):return a+b+c ... >>> func(2,3,4) 9
なんか呼び出し方が複雑になってね?
>>> def knights(): ... title = 'Sir' ... return (lambda x: title + ' ' + x) ... >>> knights()('hoge') 'Sir hoge'
>>> def knights_def(x): ... title = 'Sir' ... return title + ' ' + x ... >>> knights_def('hoge') 'Sir hoge'
lambda 式の解説が、上記あたりから始まるから、わけわからなくなるんだと思った。やっぱり lambda 式を使わないとメンドクサイよね?と思うような例をバシッと最初に示して欲しいものだ。
ちょっと使いどころがわかった例
>>> L=[(lambda x:x**2),(lambda x:x**3), (lambda x:x**4)] >>> for f in L: ... print f(2) ... 4 8 16 >>> print L[0](3) 9 >>> print L[1](3) 27 >>> print L[2](3) 81
この辺でようやく勘所が、ディクショナリとかmap関数で使うといいよ!ってのも納得できる。
ディクショナリで使った例
>>> lambda_switch={'sum':(lambda a,b:a+b), 'diff':(lambda a,b:a-b)} >>> lambda_switch['sum'](2,3) 5 >>> lambda_switch['diff'](2,3) -1
上記のように、swith/case文のような多分岐をディクショナリを使うには重宝しそう。
map関数で使った例
>>> nums=[1,1,2,3,5,8,13] >>> def sq(x): ... return x**2 ... >>> map(sq, nums) [1, 1, 4, 9, 25, 64, 169]
>>> nums=[1,1,2,3,5,8,13] >>> map((lambda x:x**2), nums) [1, 1, 4, 9, 25, 64, 169]
いちいち関数をdefする必要がない。
引数が複数ある場合は、↓みたいな感じ。
>>> nums=[1,1,2,3,5,8,13] >>> nums2=[0,1,1,2,3,5,8] >>> map((lambda x,y:x-y), nums, nums2) [1, 0, 1, 1, 2, 3, 5]