【python】mapの使い方

2021年8月17日

map()を使うとリストのすべての要素に同じ処理するすことができます。リスト(配列)の中身をすべて2倍にしたい全て整数にしたいなどです。

なぜ、for文ではなく、わざわざmap()を使うかというと、処理が早いからです。

スプレッドシートのGAS(JavaScript)でよく使っていましたが、pythonで使うのは初めてだったのでまとめてみました。

組み込み関数で処理をする場合

l=[1,-3,2,-4,-5,1]  # 全部絶対値にしたい!

例えば、上のリストのすべての要素を絶対値にしたいとき、いろいろな方法があると思いますが、一番単純なfor文を使用すると下記のようになります。

l=[1,-3,2,-4,-5,1] 
for i in range(len(l)):
    l[i] = abs(l[i])
print(l)
#[1, 3, 2, 4, 5, 1]

mapを使うと下記のようになります。

l=[1,-3,2,-4,-5,1] 
l2=list(map(abs,l))
print(l2)
#[1, 3, 2, 4, 5, 1]

map(abs,l) を日本語すると「lの要素すべてを絶対値に(ABSの処理を)してね!」って感じだと思います。

注意しなければならないことは返ってくる答えは「リスト」ではなく「イテレーター」で返ってくるのでlist()を使ってリストにする必要があります。(もちろんイテレータとして処理をしても問題ありません。)

組み込み関数以外の場合

上記のabsの部分はどんな処理をするかを明記します。int(整数に変換)やstr(文字列に変換) など、組み込み関数の場合はそのまま明記すればいいのですが、「2倍にする」や「プラス10」などの処理をする場合は「lambda(ラムダ式、無名関数)」使用します。

l=[1,-3,2,-4,-5,1] 
l2=list(map(lambda x:x+10,l))
print(l2)
#[11, 7, 12, 6, 5, 11]

日本語にすると「lの要素をxに代入して次の計算(x+10)をしてね」のような感じだと思います。

無名関数につきましてはこちらを参照してください。

さらに複雑な処理をしたい場合

各要素に対して複雑な処理をしたい場合は「defで定義した関数」を使用することができます。例えば「各要素がプラスの数値だったら100倍、マイナスの数値はそのまま」という処理をしたい場合は

def f(x):
    if x>0:
        return x*100
    else:
        return x

l=[1,-3,2,-4,-5,1] 
l2=list(map(f,l))
print(l2)
# [100, -3, 200, -4, -5, 100]

「f」という関数を用意してすべての要素を「f」で処理しています。 このようにどんな処理をしたいかを関数で定義をすることができるので、コードも書きやすく可読性も良くなると思います。

本当に早いのか

実際に早いのか測定してみます。1から10000000までの数字を3で割り切れるかを検証するコードです。まずはfor文

#-*- config:utf-8 -*-
import time

start = time.time()
result = []
l = range(10000000)
for i in range(len(l)):
    re = ""
    if l[i]%3==0:
        re=True
    else:
        re=False
    result.append(re)
stop_time = time.time() - start
print(result[:10])
print(format(stop_time)+"秒") 

# [True, False, False, True, False, False, True, False, False, True]
# 3.4706501960754395秒

約3.4秒くらいですね。次はmap()を使った場合です。

#-*- config:utf-8 -*-
import time

def f(x):
    if x%3==0:
        return True
    else:
        return False
start = time.time()
l = range(10000000)
l2=list(map(f,l))
stop_time = time.time() - start
print(l2[:10])
print(format(stop_time)+"秒") 

# [True, False, False, True, False, False, True, False, False, True]
# 1.2786169052124023秒

約2倍くらい早くなりました。ちなみにVScodeのデバッグモードで実験すると結果が逆転します。(なぜだろう・・)

map()は他にもいろいろな使い方がありますが、今回はここまでにします。

ぜひ活用してみてください。



python

Posted by Next-k