St_Hakky’s blog

Data Science / Human Resources / Web Applicationについて書きます

Effective python シリーズ7:Use List Comprehensions Instead of map and filter

こんにちは。

○読んでいる本

以下の本を勉強がてら読んでいます。

www.effectivepython.com

ここにある通り、Pythonプログラムを改良する59項目が掲載されています。詳細は本に書かれているので、それを読めば良しとして、大事そうなところと、これに関連して勉強したことを書きます。

まとめページは以下より。

st-hakky.hatenablog.com


さて、今回は7つ目:「Use List Comprehensions Instead of map and filter」をやります。

○Use List Comprehensions Instead of map and filter

mapやfilterの代わりにリスト内包表記を使おうという話ですね。

■結論

まとめると以下の2点。

  • リスト内包表記は、lambda式がいらないしmapとfilterの合わせ技も簡潔にかける
  • 辞書と集合にもリスト内包表記使えて便利

主張として、lambdaはややこしく見えるという話ですね。まぁ言わんことはわからんでもないのと、PEP8だと関数化しろって言われますし(あれはあれでどうなのって思うんですが)。

プログラムの規模が大きくなると、小さい処理とかのために、いちいち関数化しているとコードが煩雑になり、わかりにくくなるのもあるので、lambdaを関数化で回避するのもいただけない。

というので、リスト内包表記を使いましょうという話ですね。

■コード比較:2乗計算をして見る

実際にコードを見るのがいいとおもうので、そうします。

データは以下を用意。

a = [1,2,3,4,5,6,7,8,9,10]


これのデータを、リスト内包表記とmapで書いて見る。

# リスト内包表記
_list_naiho = [x ** 2 for x in a]

# map
_map = map(lambda x: x ** 2, a)

結果は同じになります。この程度のわかりやすさなら、好みかなと思ったりしなくはないですが笑んまぁ、この例だったら、ぶっちゃけどっちでもいいんじゃね笑

大量の処理をさせようとした時に色々速さはきになるところですが、以下のブログによれば、速さでいくと、リスト内包表記の方が早いと書いてありますが、ここは議論が分かれていますね(参考情報に参考リンクを貼った)

Pythonのリスト内包表記の速度 - Qiita

このような例だったら、一概に「こう」というわけでもなく、私的には可読性を元に使い分ける感じでいいのではないかと思います。

■コード比較:2で割れる数だけ2乗する

今回もデータは以下を用意。

a = [1,2,3,4,5,6,7,8,9,10]


これに対して、2で割れる数だけ2乗するコードは以下の通り。

# リスト内包表記
_list_naiho = [x ** 2 for x in a if x % 2 == 0]  

# mapとfilter
_map = map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, a)) 

これは確かにリスト内包表記の方がわかりやすいですね。mapとfilterを両方使うとごちゃごちゃしだすな(このパターンはまぁリスト内包表記ですね)