前の記事でさらっと使っていたmap関数の使い方の紹介です。
ドキュメントはこちら。
組み込み関数
MathematicaのMapとよく似た関数(と聞いて、「ああ、あれね」と通じる人がどのくらいいらっしゃるのかわかりませんが)であり、
配列などの各要素に関数を順番に適用することができます。
使い方は map(適用したい関数, 配列1, )
です。
僕はpython初心者の頃、関数を適用した結果のリストがすぐ戻ってくると期待していたのに、イテレーターが戻ってきたので結構戸惑いました。
例えば、引数を2乗する関数で試してみましょう。
def f(x):
return x**2
m = map(f, range(10))
print(m)
# <map object at 0x1156f19b0>
リストにしたければ、型変換してあげる必要があります。
ただし、通常のリストと違い、イテレーターなので、一度最後のデータかまで取り出すと、次の値が取れなくなります。
# 1回目は与えられたリストに関数を適用した結果が戻る
print(list(m))
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 続けて全く同じように呼び出すと空のリストがかえる。
print(list(m))
# []
内包表記でほぼ同じ処理を実装できますが、違いは関数が実行されるタイミングです。
内包表記は、それが定義されたタイミングで計算され、
mapの場合は、値が必要になったタイミングで実行されます。
適用する関数にprint文を仕込んで、様子を見てみましょう。
最初に内包表記の場合、
def g(x):
print(x)
return x**2
l = [g(x) for x in range(10)]
# この時点で g が実行されているので、以下が出力される。
'''
0
1
2
3
4
5
6
7
8
9
'''
print(l)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
次にmapの場合。
m1 = map(g, range(10))
# まだgが実行されてないので、何も出力されない。
# nextを使って、最初の3個の値を取り出すと、その3この値に対してだけ関数gが実行される。
print(next(m1))
'''
0
0
'''
print(next(m1))
'''
1
1
'''
print(next(m1))
'''
2
4
'''
これらの性質により、上手く使えば実行時間やメモリの節約が可能になるそうです。
(それを実感するほど上手く使えたことはほとんどないのですが)
ただ、pythonを使っていく上で、イテレーターの扱いに慣れておくのは有益なので、学んでおいて損はなかったと思ってます。