map()は、イテラブルの要素を任意の関数に渡して新たなイテレータオブジェクトを生成する関数です。例えば、
- リストの文字列の数字の要素をまとめてint型に変換したい
- リストの各要素の数値をある関数に適用して、その結果を新しいリストで生成したい
こんな場面に使えます。尚、同様の機能はforループや内包表記を使って書くことも出来ますが、可読性や実行効率を考慮して使い分けるのが良いと思います。
# 2020/2/11 記事更新
確認した環境
- OS: Ubuntu 16.04LTS
- Python3.7.4
map()の使いかた
map() は、元となるイテラブル (リスト、文字列等)の各要素を任意の関数に渡して、新しいイテレータオブジェクトを生成します。
基本の書式
map(function, iterable, ...)
- 第一引数function: 任意の関数
- 第二引数以降iterable: 元となるイテラブル(複数とれます)
iterableの各要素を、funcionで指定した関数に渡して処理を行います。
iterableが複数ある場合は、functionはその数だけ引数を取る必要があります。
具体的な使用例
map()の返却値はイテレータなので、下記の例ではlistに変換します。
- リストの各要素をint型からstr型へ変換
functionとしてstr()を設定します。
>>> a = [1, 2, 3, 4, 5]
>>> list(map(str, a))
['1', '2', '3', '4', '5']
functionとしてint()を設定します。
>>> b = ['1', '2', '3', '4', '5']
>>> list(map(int, b))
[1, 2, 3, 4, 5]
# 関数を定義
>>> def func(n):
... return n**2
>>> a = [1, 2, 3, 4]
>>> list(map(func, a))
[1, 4, 9, 16]
functionはlambda式も使えます。
>>> a = [1, 2, 3]
# lambda式を設定
>>> list(map(lambda x:x**2, a))
[1, 4, 9]
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
# 関数を定義
>>> def func(i, j):
... return (i, j)
>>> list(map(func, a, b))
[(1, 4), (2, 5), (3, 6)]
# ちなみに、これはzip()と同じ機能ですね
>>> list(zip(a, b))
[(1, 4), (2, 5), (3, 6)]
# 関数を定義
>>> def func(s1, s2):
... return s1 + s2
# 文字列の場合
>>> a = 'abc'
>>> b = 'def'
>>> list(map(func, a, b))
['ad', 'be', 'cf']
# 辞書の場合
>>> d = {'a':1, 'b':2, 'c':3}
>>> f = {'d':9, 'e':8, 'f':7}
>>> list(map(func, d, f))
['ad', 'be', 'cf']
引数に設定されたiterableの長さが異なる場合は、最も短いiterableの長さになります。
# 長さの異なるiterable
>>> a = [1, 2, 3]
>>> b = [4, 5, 6, 7, 8, 9]
>>> def func(i, j):
... return (i, j)
# 短い方のiterableが尽きたら終了
>>> list(map(func, a, b))
[(1, 4), (2, 5), (3, 6)]
(参考)forループ、内包表記との比較
参考までに、同じ動作について、forループと内包表記 の場合と書き方を比較してみました。
- forループの場合
>>> a = [1, 2, 3]
>>> b = []
>>> for i in a:
... b.append(i**2)
>>> b
[1, 4, 9]
>>> a = [1, 2, 3]
>>> b = list(map(lambda x:x**2, a))
>>> b
[1, 4, 9]
>>> a = [1, 2, 3]
>>> b = [i**2 for i in a]
>>> b
[1, 4, 9]
intertools.starmap()の使いかた
iterableの要素が既にタプルで構成されていて、functionの引数にそのまま適用出来る場合は、itertools.starmap() が使えます。
>>> import itertools
# イテレータの各要素がタプルでまとまっている
>>> a = [(1, 2), (2, 2), (3, 2)]
>>> def func(n, p):
... return n**p
>>> list(itertools.starmap(func, a))
[1, 4, 9]
まとめ
map()関数を用いて、イテラブルの要素を任意の関数に適用して新たなイテレータを生成する方法についてまとめました。同様の機能はforループや内包表記を使って書くことも出来ます。可読性や実行効率なども考慮しながら使いこなしていきたいですね。
コメント
[…] 参考)[Python] リストの各要素のデータ型を変換する:map関数の使いかた […]