🐥

map()って何?

2023/07/04に公開

map関数

今回はmap()って何?って人向けに解説をしていきます。

map関数は、第一引数の関数を第二引数以降の要素に適用する関数です。
はい。なんのこっちゃだと思うので以下にコードで例を示します。

def plus_one(x):
    return x+1

value = [0,1]
value = map(plus_one,value)

print(list(value))
# map関数は<map object>を返すため、一度list()や、forループで値を取り出す必要があります。
[1, 2]

map関数により、plus_one関数をvalueに適用しています。

ここでplus_oneはxという引数を受け取る必要がありますが、これはmap関数が自動的にvalueの要素をxへ渡しています。
そのため、このコードはplus_one(value[0]),plus_one(value[1])という計算と同じことを行なっています。
このように複数の要素に対して一度に関数の適用を行えることがmap()関数の利点となります。

また、map関数は二つ以上の引数を持つことも可能です。
例えば、

def x_plus_y(x,y):
    return x+y

values1 = [1, 2, 3, 4]
values2 = [5, 6, 7, 8]
sums = map(x_plus_y, values1, values2)

print(list(sums))
[6, 8, 10, 12] # [1+5,2+6,3+7,4+8]

これはx_plus_yの引数x,yにvalues1,values2を代入し、その結果をsumsとして受け取っています。
このように、「複数の値にまとめて関数を定義したい時」に使うと良いと思います。

以上でmap関数の解説は終了です!読んでいただいてありがとうございました。

おまけ:<map object>について

mapオブジェクトについて、もう少し詳しく知りたい人に向けたおまけです。

map関数は、mapオブジェクトと呼ばれるイテレータを返します。
map関数からの出力をそのままprintすると、

def plus_one(x):
    return x+1

value = [0,1]
value = map(plus_one,value)

print(value)
<map object at 0x7fdda840a100>

この様な表示になります。

このようなmapオブジェクトは、「どの関数をどの要素に適用するか」という情報のみを保持しており、いわば「計算の指示」を保持しています。
実はこの時点では計算は行われておらず、list()や、forループなどで値を出力するときに関数が実行され、計算結果が出力されます。

こんな方法になっている一つの理由は、メモリ容量の効率化のためです。
上記の様な簡単な計算ではメモリを圧迫しませんが、これが大量のデータになるとその計算はメモリを圧迫します。そのため、必要になった時点で計算を行う方式が利用されています。
これにより全てのデータの結果が必要でない場合や、ファイルに値を直接書き込む場合などにメモリを節約することができます。

またイテレータは特殊な二つの特性を持ちます。

  1. 一度のみ利用可能な値であり、一度list()やforループで計算を行うと、その値は使い果たされて利用できなくなります。
    以下に例を示します。
def plus_one(x):
    return x+1

value = [0,1]
value = map(plus_one,value)

print(list(value))
print(value)
print(list(value))
print(value)
[1, 2]
<map object at 0x7f83902d2100>
[]
<map object at 0x7f83902d2100>

このように、value自体はイテレータであり「計算手法を示すもの」なので変化しませんが、一度計算を行うとその要素は使い果たされ利用できなくなります。

この点もメモリの節約の観点で有効ですが、実際に使用する際には注意が必要です。

  1. イテレータの計算は一つずつ行われます。
    通常、多量のデータを計算する際は、その全てのデータがメモリに読み込まれますが、イテレータでは計算を一要素ずつ行なっていきます。そして計算が終わればその値を消去し、次の計算を行います。
    これはビッグデータの処理の際、メモリ圧迫の回避に非常に役に立ちます。

mapオブジェクト、及びイテレータの詳細は以上になります。
それでは、最後まで読んでいただきありがとうございました!

Discussion