【Python】map関数の使い方の基本 ~要素への関数適用~

Python の組み込み関数の map 関数を使って要素へ関数を適用する方法を解説します。
目次
map 関数で要素へ関数を適用する
map 関数は、関数と処理対象のイテラブルを受け取って、イテラブルの各要素に関数を適用した結果を返す Python の組み込み関数です。
このように引数に関数を受け取る関数は高階関数と言います。for 文で処理しても同じ処理ができますが、繰り返し処理を書かずにシンプルに記載できる点がメリットです。
map 関数は、関数型プログラミング言語において中心的な関数です。Python はマルチパラダイムの言語と言われているため、厳密ではありませんが関数型のプログラミングスタイルもサポートしており、map 関数が組み込み関数として利用できます。
本記事では、リストの要素へ関数を適用する例を用いて、map 関数の使い方の基本を紹介します。
map 関数の基本的な使い方
map 関数の基本的な構文は以下のようになります。
result = map(関数, イテラブル)
複数の引数を取る関数を指定する場合には、以下のようにイテラブルを列挙して指定することができます。
result = map(関数, イテラブル1, イテラブル2, ...)
map 関数では、イテラブルの各要素に関数を適用した結果のイテレータを返却します。イテレータは値を逐次取り出せるオブジェクトで、nextを用いることで順に関数を適用した値を取り出したり、for 文で使用したりすることができます。後述の例でも見ますが、list(map(関数, イテラブル)) のようにすることでリストに変換して取得することも可能です。
また、map(関数, イテラブル1, イテラブル2, ...)というように複数のイテラブルを渡す場合には、関数は引数としてイテラブルの数だけ受け取れる必要があります。
基本的な使い方
map 関数の基本的な使い方を以下の例を用いて見ていきましょう。
def square(x):
"""値を2乗する"""
return x**2
if __name__ == "__main__":
tmp_list = [1, 2, 3, 4, 5]
# map関数を適用し、イテレータを取得
result = map(square, tmp_list)
print(result, "\n")
# nextで1要素ずつ結果データを取得
print(next(result))
print(next(result))
print(next(result))
print(next(result))
print(next(result))【実行結果】 <map object at 0x0000018E82BC2A70> 1 4 9 16 25
上記の例では、受け取った値を 2 乗する square という関数が定義されており、tmp_list の各要素に適用しています。
map 関数を呼び出している部分では「map(square, tmp_list)」というように関数と処理対象のリストを渡しています。ここでポイントは、関数を渡す際に () がないことです。関数は square(2) のように () で引数を指定すると関数を実行することを意味しますが、() がない場合は関数そのものを表します。map 関数は、受け取った square という関数を内部で実行しているわけです。
map 関数の返却値は「map object」となっていますが、これはイテレータの一種です。next 関数を使用することで次の要素を順番に取得することができます。この例では、tmp_list の要素それぞれを2乗した結果が順に取得されていることが分かります。
リストやタプルで取得する場合
map 関数の返却値はイテレータであるため、以下のように list や tuple に変換することができます。
def square(x):
"""値を2乗する"""
return x**2
if __name__ == "__main__":
tmp_list = [1, 2, 3, 4, 5]
# map関数を適用し、リストで取得
result_list = list(map(square, tmp_list))
print(result_list)
# map関数を適用し、タプルで取得
result_tuple = tuple(map(square, tmp_list))
print(result_tuple)【実行結果】 [1, 4, 9, 16, 25] (1, 4, 9, 16, 25)
複数イテラブルを指定する場合
map 関数は複数のイテラブルを受け取り、それらに対してまとめて関数を適用することができます。以下の例では、make_variable_set という関数が 3 つの引数を受け取り、それらをタプルとして返す動作をします。
def make_variable_set(x, y, z):
"""各引数を並べたタプルを返却する"""
return x, y, z
if __name__ == "__main__":
nums1 = [1, 2, 3]
nums2 = [4, 5, 6]
nums3 = [7, 8, 9]
# map関数で複数のイテラブルを渡す
# 関数側もイテラブルの数だけの引数を受け取れる必要がある
result = list(map(make_variable_set, nums1, nums2, nums3))
print(result)【実行結果】 [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
この結果を見ると、3 つのリストの各要素が関数によってタプルとしてまとめられて返されていることが確認できます。
複数のイテラブルの要素数が異なる場合
map 関数を使用する際、複数のイテラブルを指定することができますが、それらの要素数が異なる場合の挙動に注意が必要です。
具体的には、map 関数は、最も短いイテラブルの要素数に合わせて処理を行います。これは最も短いイテラブルが終了した時点で、他のイテラブルの残りの要素は無視されることを意味します。
def make_variable_set(x, y, z):
"""各引数を並べたタプルを返却する"""
return x, y, z
if __name__ == "__main__":
nums1 = [1, 2, 3]
nums2 = [4, 5, 6, 7, 8, 9]
nums3 = [10, 11, 12, 13, 14]
# map関数で複数のイテラブルを渡す
# 最も短いイテラブルが消費されたら終了
result = list(map(make_variable_set, nums1, nums2, nums3))
print(result)【実行結果】 [(1, 4, 10), (2, 5, 11), (3, 6, 12)]
この例では、3 つの要素を使用していますが、最も短いイテラブルである nums1 に合わせて処理が行われるため、nums2 の 7、8、9 や nums3 の 13、14 については結果に含まれていないことが分かります。
ラムダ関数(無名関数)と組み合わせる場合
map 関数は、ラムダ関数(無名関数)と組み合わせることで、より手軽に要素に対して関数を適用することができます。ラムダ関数は、関数定義を def で定義することなく、その場で作れるもので関数型プログラミングでは中核の概念です。
square 関数をラムダ関数にして map 関数で使う例を見てみましょう。
tmp_list = [1, 2, 3, 4, 5] # map関数を適用し、リストで取得 result = list(map(lambda x: x**2, tmp_list)) print(result) # map関数を適用し、タプルで取得 result = tuple(map(lambda x: x**2, tmp_list)) print(result)
【実行結果】 [1, 4, 9, 16, 25] (1, 4, 9, 16, 25)
これまでの例で square と関数を指定していた部分に「lambda x: x**2」というラムダ関数を指定しています。結果は square 関数を使った場合と同じす。
ラムダ関数は無名関数ともいわれる通り、関数名はありませんが、そのものが関数として扱われるため、map 関数に渡すことでリストの各要素に関数を適用できます。
まとめ
Python の組み込み関数である map 関数を使って要素へ関数を適用する方法を解説しました。
map 関数は、関数と処理対象のイテラブルを受け取って、イテラブルの各要素に関数を適用した結果を返す Python の組み込み関数です。map 関数は他の関数型プログラミング言語でも中心的な関数で Python でも使用できます。
map 関数は for 文を用いなくてもシンプルに関数の適用ができることが特徴です。非常に強力な機能ではありますが、map 関数の適用が常に最適な選択というわけではありません。
場合によっては for 文で書いた方が可読性が上がる可能性もあります。目的に応じて適切に方法を選択できるよう map 関数の使い方を理解しておくようにしましょう。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。



.jpg)
関数-_yieldによる返却_.jpg)
の基本的な使い方.jpg)
内包表記の使い方.jpg)
の使い方.jpg)