高階関数とラムダ式

INPUT · スライド

いちばんを1行で見つける

01 / 07

第2章で手で書いた型

「いちばん点が高い人を探す」。第2章の総合演習でやったのを覚えているかな。

1件目をとりあえず1位にしておいて、上回るものが出たら入れかえる。この形だったね。

書けること自体は大事だけれど、毎回これを書くのはさすがに面倒だ。

meibo = [    {"namae": "ゆい", "ten": 90},    {"namae": "はると", "ten": 60},    {"namae": "みなと", "ten": 75},]saikou = meibo[0]for hito in meibo:    if hito["ten"] > saikou["ten"]:        saikou = hitoprint(saikou["namae"])

実行結果

ゆい

02 / 07

max と min

Pythonには最初から max(マックス)と min(ミン)が用意されているよ。リストを渡すと、いちばん大きいもの・いちばん小さいものが返ってくる。

数のリストなら、これだけで済んでしまう。

tens = [80, 45, 95]print(max(tens))print(min(tens))

実行結果

95
45

03 / 07

辞書のリストだと困る

では、さっきの名簿をそのまま max に渡すとどうなるか。エラーになるよ。

辞書どうしは「どちらが大きいか」を決められないからだね。Pythonは勝手に推測せず、くらべかたが分からないと正直に言ってくるんだ。

meibo = [    {"namae": "ゆい", "ten": 90},    {"namae": "はると", "ten": 60},]print(max(meibo))

実行結果

TypeError: '>' not supported between instances of 'dict' and 'dict'

04 / 07

key で「何をくらべるか」を教える

sorted とまったく同じ key が、max と min にも渡せるよ。

key=lambda h: h["ten"] と書けば、「1人ぶんの h から h["ten"] を取り出して、その数でくらべてくれ」という意味になる。

前のスライドの5行が、これで1行だよ。

meibo = [    {"namae": "ゆい", "ten": 90},    {"namae": "はると", "ten": 60},    {"namae": "みなと", "ten": 75},]saikou = max(meibo, key=lambda h: h["ten"])print(saikou["namae"])

実行結果

ゆい

05 / 07

返ってくるのは要素そのもの

ここを取りちがえやすいので、はっきりさせておくよ。

max(meibo, key=...) が返すのは、いちばん大きかった点数ではない。その点数を持っていた要素そのもの、つまり辞書が丸ごと返ってくる。

だから名前も点数も、そのまま取り出せる。「いちばん点が高い人は誰か」を知りたいのだから、これはとてもありがたい動きだね。

meibo = [    {"namae": "ゆい", "ten": 90},    {"namae": "はると", "ten": 60},]saikou = max(meibo, key=lambda h: h["ten"])print(saikou)print(saikou["ten"])

実行結果

{'namae': 'ゆい', 'ten': 90}
90

06 / 07

min も len も同じ

min の使いかたは max とまったく同じ。いちばん安いものを探すときに使うよ。

key に渡すのが lambda でなくてもいいのも sorted と同じ。いちばん文字数が多い名前なら key=len で足りるね。

shinamonos = [    {"namae": "りんご", "nedan": 300},    {"namae": "みかん", "nedan": 100},]yasui = min(shinamonos, key=lambda s: s["nedan"])print(yasui["namae"])namaes = ["はると", "ゆい", "みなと"]print(max(namaes, key=len))

実行結果

みかん
はると

07 / 07

数えあげの道具がそろった

max と min のなかまに sum(サム)もあるよ。数のリストを渡すと合計が返ってくる。第2章で goukei に足しこんでいたあれが1行になるんだ。

sum には key が無いので注意。合計するものは自分で作って渡す——内包表記の出番だね。

ここまでで、key に関数を渡すという形は3つの道具で共通だと分かったはず。次のグループでは、map と filter、そして自分で作った関数に関数を渡す話に進むよ。

meibo = [    {"namae": "ゆい", "ten": 90},    {"namae": "はると", "ten": 60},    {"namae": "みなと", "ten": 75},]tens = [h["ten"] for h in meibo]print(sum(tens))print(sum(tens) // len(tens))print(max(tens) - min(tens))

実行結果

225
75
30