周回遅れでIT業界デビューしたエンジニアのブログ

就職氷河期にモロにぶち当たり、人生で混迷を極めた末にIT業界に安寧を見出そうとしているアラフォーのお勉強日記です。

Pythonでfor文とlambdaの書き方&速度を比較してみた

こんにちは。もうそろそろ一年も終わりですね。
私はいろいろ環境が激変した年でした。
皆様にとっては、今年はどんな年でしたか?


f:id:sionff:20180119162019j:plain

Pythonでlambdaを使おう

できるだけ簡潔で高速なコードを書けるようになりたくて、lambdaをおさらいしました。そこで、まずはfor文とlambdaで同じ処理を書いて比較してみました。

map() ... すべての要素に処理を行う

# for文
xlist = []
for x in range(1,5):
    xlist.append(x * 2)
# [2,4,6,8]


# lambda
list(map(lambda x: x * 2, range(1,5)))
# [2,4,6,8]

filter() ... 条件に一致する要素のみ抽出する

# for文
xlist = []
for x in range(10,20):
    if x % 2 is 1:
        xlist.append(x)
# [11,13,15,17,19]


# lambda
list(filter(lambda n: n % 2 is 1, range(10,20)))
# [11,13,15,17,19]

reduce() ... 全部まとめて1つにする

# reduce関数はpython3ではグローバル名前空間から取り除かれてしまったので、
# functoolsというモジュールをインポートする
from functools import reduce


# for文
x = 0
for i in range(0,20):
    x = x + i
# 190


# lambda
reduce(lambda ans, x: ans + x, range(0,20))
# 190

結果として出てくるものはそれぞれ同じなのですが、途中の書き方が全然が違う!

ちなみに速度は?

以下の方法で比較しました。

# 「x * 2」を1億回まわしてリストを返す処理

# 動作時間を比較
import time

# for文で処理した場合
now = time.time()
xlist = []
for x in range(100000000):
    xlist.append(x * 2)
print("所要時間:", time.time() - now, "秒")
# 所要時間: 18.96997570991516 秒


# map()で処理した場合
now = time.time()
list(map(lambda x: x * 2, range(100000000)))
print("所要時間:", time.time() - now, "秒")
# 所要時間: 15.73539137840271 秒


# 内包表記で処理した場合
now = time.time()
[x * 2 for x in range(100000000)]
print("所要時間:", time.time() - now, "秒")
# 所要時間: 10.016270875930786 秒

結果は「内包表記 > map() > for文」となりました。

それでもmap()が重要な理由

一番速いのは内包表記でした。

が、実は関数型プログラミングが最近気になっていて、手始めにこれらの高階関数を触っておく必要があったのです。

高階関数とは、関数を引数にしたり、関数を戻り値とするような関数のことで、上の例でいえばmapもfilterもreduceもlambda(無名関数)を引数に取っています。

関数型プログラミングについては色々記事が出ています。Pythonではここが一番分かりやすかったので、もし興味がありましたら↓をお勧めしたいと思います!
postd.cc