01 / 07
もう内包表記でできている
「リストの中身を全部2倍にしたい」。第9章で、これは1行で書けるようになったね。
この章ではもうひとつの書きかたを覚えるよ。map(マップ)という組み込みの関数だ。
できることは内包表記とほとんど同じ。それでもわざわざ覚えるのは、他人の書いたコードに出てくるからだよ。書けなくてもいいけれど、読めないと困るんだ。
kazus = [1, 2, 3]print([x * 2 for x in kazus])実行結果
[2, 4, 6]
高階関数とラムダ式
INPUT · スライド
01 / 07
「リストの中身を全部2倍にしたい」。第9章で、これは1行で書けるようになったね。
この章ではもうひとつの書きかたを覚えるよ。map(マップ)という組み込みの関数だ。
できることは内包表記とほとんど同じ。それでもわざわざ覚えるのは、他人の書いたコードに出てくるからだよ。書けなくてもいいけれど、読めないと困るんだ。
kazus = [1, 2, 3]print([x * 2 for x in kazus])実行結果
[2, 4, 6]
02 / 07
map には関数と回せるものの2つを渡す。
map(f, xs) … xs の中身ひとつずつに f をかける渡すのは関数そのものなので、nibai にカッコを付けない。付けたら「呼んだ結果」を渡すことになってしまう。前のグループの key=len とまったく同じ話だね。
そして、返ってくるのはリストではない。map という専用の種類の値だよ。
def nibai(x): return x * 2kazus = [1, 2, 3]m = map(nibai, kazus)print(type(m))実行結果
<class 'map'>
03 / 07
ここが map のいちばんの落とし穴。そのまま print しても中身は出てこない。
kazus = [1, 2, 3]print(map(nibai, kazus))<map object at 0x1234abcd>うしろの番地は実行するたびに変わる。答え合わせには使えないし、そもそも読んでも何も分からないよね。
なぜこうなるかというと、map はまだ計算していないからだよ。第8章でやった「1つずつ配る係」——イテレータ——と同じで、頼まれてはじめて1つ作る。「これから2倍にしますよ」という予約票を受け取った状態なんだ。
04 / 07
予約票を実際の値に変えるには、list(...) を通す。中身を全部取り出してリストにしてくれるよ。
map を使ったら list で受ける。これをひとつの型として覚えてしまおう。表示するときも、あとでリストとして使いたいときも、通しておけば間違いがない。
def nibai(x): return x * 2kazus = [1, 2, 3]print(list(map(nibai, kazus)))実行結果
[2, 4, 6]
05 / 07
同じことをする2つを並べてみよう。結果はまったく同じだよ。
list(map(nibai, kazus))[nibai(x) for x in kazus]どちらが読みやすいかは、正直なところ好みもある。ただPythonでは内包表記のほうが好まれることが多い。list で包む手間が要らないし、2倍くらいの処理なら lambda も def も書かずに x * 2 と直接書けるからね。
def nibai(x): return x * 2kazus = [1, 2, 3]a = list(map(nibai, kazus))b = [nibai(x) for x in kazus]print(a)print(b)print(a == b)実行結果
[2, 4, 6] [2, 4, 6] True
06 / 07
もうひとつ、予約票であるがゆえの性質がある。一度取り出すと、2回目は空っぽだよ。
第8章でやったね。イテレータは配り終わると巻き戻せない。map もまったく同じ性質を持っているんだ。
だから結果を2回使いたいなら、先に list にして変数に入れておくこと。予約票のまま持ち回ると、2回目に空のリストが出てきて頭を抱えることになるよ。
def nibai(x): return x * 2kazus = [1, 2, 3]m = map(nibai, kazus)print(list(m))print(list(m))実行結果
[2, 4, 6] []
07 / 07
自分で新しく書くなら、内包表記のほうをすすめる。list で包み忘れる事故も、2回目が空になる事故も起きないからね。
それでも map を覚えるのは、読めないと困るから。他の言語から来た人は map で書くことが多いし、ライブラリの中にも出てくる。
両方読めるようにしておく。それがこのレッスンの目標だよ。次は「全部にかける」ではなく「いるものだけ残す」ほうをやろう。