高階関数とラムダ式

INPUT · スライド

基準を渡して並べかえる

01 / 07

そのままだと思ったとおりに並ばない

第2章で sorted を覚えたね。リストを渡すと並べかえた新しいリストが返ってくる、あれだよ。

でも「文字数の短い順に並べたい」となると、そのままでは困る。sorted は文字を五十音の順に並べてしまうからね。

namaes = ["はると", "ゆい", "みなと"]print(sorted(namaes))

実行結果

['はると', 'みなと', 'ゆい']

02 / 07

key で基準を教える

sorted には key という名前つきの引数がある。ここに関数を渡すと、「その関数を通した結果」で並べてくれるよ。

文字数なら len だね。key=len と書くだけで、文字数の短い順になる。

namaes = ["はると", "ゆい", "みなと"]print(sorted(namaes, key=len))

実行結果

['ゆい', 'はると', 'みなと']

03 / 07

len にカッコを付けていない

いちばん大事なのはここ。key=len であって key=len() ではない。

  • len() … 関数を呼ぶ。呼んだ結果を渡すことになる
  • len … 関数そのものを渡す

sorted がほしいのは「文字数を数える方法」であって、どこかの文字数という答えではないんだ。あとで自分で呼ぶから、道具をそのまま貸してくれと言っている。

カッコを付けてしまうと、下のようにエラーになるよ。

namaes = ["はると", "ゆい", "みなと"]print(sorted(namaes, key=len()))

実行結果

TypeError: len() takes exactly one argument (0 given)

04 / 07

その場かぎりの基準は lambda で

len のように、ちょうどいい関数がいつもあるとは限らない。

たとえば「年齢の若い順に並べたい」。1人ぶんの辞書を受け取って toshi を返す関数がほしいけれど、そんなものは用意されていないよね。

ここで前のレッスンの lambda が効いてくる。その場で作って、その場で渡す。名前を付ける価値も無いくらい小さいので、まさに lambda の出番だよ。

key=lambda h: h["toshi"] は「1人ぶんの h を受け取って、h["toshi"] を返す関数」。この数で並べてくれ、という意味だね。

hitos = [    {"namae": "ゆい", "toshi": 20},    {"namae": "はると", "toshi": 15},    {"namae": "みなと", "toshi": 18},]for hito in sorted(hitos, key=lambda h: h["toshi"]):    print(hito["namae"])

実行結果

はると
みなと
ゆい

05 / 07

逆順と組み合わせる

第2章でやった reverse=True は、key と同時に使えるよ。カンマで並べて書くだけ。

「年齢の高い順」なら key で年齢を取り出して、reverse=True でひっくり返す。基準を決める役と、向きを決める役で、仕事が分かれているんだ。

hitos = [    {"namae": "ゆい", "toshi": 20},    {"namae": "はると", "toshi": 15},    {"namae": "みなと", "toshi": 18},]for hito in sorted(hitos, key=lambda h: h["toshi"], reverse=True):    print(hito["namae"])

実行結果

ゆい
みなと
はると

06 / 07

sort にも同じように渡せる

元のリストごと並べかえる sort のほうにも、まったく同じように key を渡せるよ。

第2章の使い分けもそのまま。元を残したいなら sorted、元ごと並べかえていいなら sort。key が増えてもこの判断は変わらないよ。

namaes = ["はると", "ゆい", "みなと"]namaes.sort(key=len)print(namaes)

実行結果

['ゆい', 'はると', 'みなと']

07 / 07

何が起きているのか

sorted は中で、渡された関数を要素ひとつひとつに呼んでいる。key=len なら、len("ゆい") len("はると") と全員ぶん呼んで、返ってきた数で並べているんだ。

つまり sorted は、並べかたの一部を呼ぶ側にまかせている。こういう「関数を受け取る関数」を高階関数(こうかいかんすう)と呼ぶよ。

次のレッスンでは、同じ key が max と min にも渡せることを見よう。第2章で5行かけて書いた「いちばん大きいものを探す」が、1行になるよ。