Python初心者講座(map関数を使ってみよう)

Python初心者講座(map関数を使ってみよう)

Python初心者向け、map関数の使い方




リスト要素に任意の処理を適用、map関数のキホン的な使い方

ナノネ、今回はPythonの組み関数『map』のキホン的な使い方を学ぼう。

map関数?、他の人が書いたコードではよく見かけるけど、自分では使ったことないなぁ。

いつも使うのはifとfor文ばっかりだもんね...。Pythonには便利な関数がたくさんあるから、少しずつ慣れていこう。

モモノキ、map関数を使うとどんなことができるの?

map関数はリストやタプルなどから一つずつ要素を取り出して、取り出した要素に対して指定した関数を適用させることができるよ。map関数の動作はコードと結果を見た方が分かりやすいから、実際にやってみよう。

In [1]:
def add_1(x):
  return x + 1 # 引数に1を足す

num_list = [1, 2, 3, 4, 5]
map_obj = map(add_1, num_list)
print(map_obj)
<map object at 0x7f44b285b3c8>

map関数の使い方は、適用したい関数とリスト(もしくはタプルでも)を引数で渡せたばOKだよ。ちなみにmap()関数の返り値はmapオブジェクトになっているから注意ね。

処理結果が直接リストとかで戻ってくるわけでは無いだね。処理した結果が欲しいときはどうするの?

mapオブジェクトに対して、for文で要素を取り出したり、リスト化したりすると、処理した結果が取得できるよ。

In [2]:
for v in map_obj:
  print(v)
2
3
4
5
6

リスト化でも結果を取り出してみる。エィッ!

In [3]:
list(map_obj)
Out[3]:
[]

空っぽだった?

ナノネ、mapオブジェクトを1回使い切っちゃうとうと、空になるみたいだよ。mapオブジェクトをもう一度作り直してみて。

1回切りって、ずいぶんケチくさい仕様だねぇ。もう1回mapオブジェクトを作り直して、エィッ!

In [4]:
map_obj = map(add_1, num_list)
list(map_obj)
Out[4]:
[2, 3, 4, 5, 6]

今度は目的の結果が出た。

適用する関数を変更したり、タプルも使えるよ。

In [5]:
def multi_2(x):
  return x * 2

num_tuple = (1, 2, 3, 4, 5)
map_obj = map(multi_2, num_tuple)

for v in map_obj:
  print(v)
2
4
6
8
10
In [0]:
 

関数に渡す引数は2個以上にしても動作するよ。こんな感じで。

In [6]:
def add_2para(x1, x2):
  return x1 + x2

num_list1 = [1, 2, 3, 4, 5]
num_list2 = [10, 20, 30, 40, 50]
map_obj = map(add_2para, num_list1, num_list2)

for v in map_obj:
  print(v)
11
22
33
44
55
In [0]:
 

2つのリストから要素を一つずつ取り出して、関数の中で足し合わせているんだね。

数値だけじゃくて、文字とかでもOKだよ。こんな感じ。

In [7]:
def concat_2para(s1, s2):
  return s1 + s2

str_list1 = ["AA", "BB", "CC", "DD", "EE"]
str_list2 = ["aa", "bb", "cc", "dd", "ee"]
map_obj = map(concat_2para, str_list1, str_list2)

for v in map_obj:
  print(v)
AAaa
BBbb
CCcc
DDdd
EEee

参考までだけど、map関数は遅延処理で実行されるよ。mapオブジェクトが作られた段階では、まだ指定した関数は適用されないんだ。関数が呼び出されるのは実際に要素を取り出すときになるよ。下のコードを実行すると動きがわかるかなぁ。

In [8]:
def add_1(x):
  print("add_1({}) was called.".format(x)) # 関数の呼び出し確認用
  return x + 1

num_list = [1, 2, 3, 4, 5]
map_obj = map(add_1, num_list)
print(map_obj)
# この段階では、まだadd_1()関数呼び出されていない
<map object at 0x7f44b1fef4e0>
In [9]:
for v in map_obj: # 要素を取り出す際にadd_1関数が呼び出される
  print(v)
add_1(1) was called.
2
add_1(2) was called.
3
add_1(3) was called.
4
add_1(4) was called.
5
add_1(5) was called.
6

なんとなく、動きが分かったかも。

簡単な関数処理なら、ラムダ式に変更しても同じように動作するよ。

In [10]:
num_list = [1, 2, 3, 4, 5]
map_obj = map(lambda x: x + 1, num_list)

for v in map_obj:
  print(v)
2
3
4
5
6

ラムダ式は知っているだんけど、うまく使いこなせてないなぁ...よくスペルを間違えちゃうし。

モモノキ、map関数の使い方は少し理解したんだけど...。

In [11]:
def calc_add1(x):
  return x + 1

num_list = [1, 2, 3, 4, 5]
for i in num_list:
  print(calc_add1(i))
2
3
4
5
6

上のいつも通りのコードでも同じ結果が取得できるよね。map関数を使うと何かいいことあるの??

目的が達成できれば、ナノネの好きな書き方でもいいと思うけど。ただ、いろんなコード書き方に慣れておくのは、きっと今後のためになるよ。特に他の人が書いたコードを理解する際は必須知識になるね。

あと、map()関数はチョットだけ処理が速い?って聞いたことがあるよ。実際に試してみよう(Jupyter Notebookのマジックコマンド%%timeitで処理時間を計測)。

In [0]:
def mycalc(x):
  return x ** 2
In [13]:
%%timeit
# map関数
nums = range(10000)
map_obj = list(map(mycalc, nums))
calc_list = list(map_obj)
100 loops, best of 3: 3.53 ms per loop
In [14]:
%%timeit
# for文でリストにappend
nums = range(10000)
calc_list = []
for i in nums:
  calc_list.append(mycalc(i))
100 loops, best of 3: 4.66 ms per loop
In [15]:
%%timeit
# リスト内包表記
nums = range(10000)
calc_list = [mycalc(i) for i in nums]
100 loops, best of 3: 4.02 ms per loop

確かに、試した中ではmap()関数が速いかも。今度からmap()関数も使えるように、少しずつ練習してみるよ。

今回のmap()関数の練習は以上で。またね!

お疲れさまでした。またね!







スポンサーリンク

0 件のコメント :

コメントを投稿