ループを使わない書き方

map関数

Pythonではfor文でのループよりもmap関数を使うのがいいコードとのことです。

例えば文字列を数字に変換する場合、for文で書くと次のようになります。

1
2
3
4
5
6
7
in_data = ["1", "2", "3"]

out_data = []
for d in in_data:
out_data.append(int(d))

print(out_data) # 出力 [1, 2, 3]

map関数で書き換えると下記のようになります。

1
2
3
4
5
in_data = ["1", "2", "3"]

out_data = map(int, in_data)

print(list(out_data)) # 出力 [1, 2, 3]

だいぶコンパクトなコードになりいい感じです。

上記は関数のとる引数が1つの場合ですが、引数を複数とる関数の場合はカンマで区切って別のリスト型変数を指定すればいいです。

1
2
3
4
5
in_data1 = [1, 2, 3]
in_data2 = [1, 2, 3]

out_data = map(lambda x,y:x+y, in_data1, in_data2)
print(list(out_data)) # 出力 [2, 4, 6]

引数のデータサイズ数が違う場合は自動で短い配列の方に合わせられるようです。

1
2
3
4
5
in_data1 = [1, 2, 3]
in_data2 = [1, 2]

out_data = map(lambda x,y:x+y, in_data1, in_data2)
print(list(out_data)) # 出力 [2, 4]

filter関数

リスト型データからある条件に合致するデータを抽出します。
filter関数の第一引数は抽出用の関数で、第二引数はデータとなります。

1
2
3
4
5
6
7
8
in_data = ['a.txt', 'b.doc', 'c.txt', 'd.jpg']

def is_txt(x):
return x.endswith('.txt')

out_data = filter(is_txt, in_data)

print(list(out_data)) # 出力 ['a.txt', 'c.txt']

関数を別定義するのはちょっとまどろっこしい感じがしますが、下記のようにlambdaを使うと1行で書けるようになり便利&シンプルです。

1
2
3
4
5
in_data = ['a.txt', 'b.doc', 'c.txt', 'd.jpg']

out_data = filter(lambda x: x.endswith('.txt'), in_data)

print(list(out_data)) # 出力 ['a.txt', 'c.txt']

reduce関数

配列のすべてのデータに関して順次処理を行います。
ポイントとしては第一引数には引数を2つとる関数を指定します。
Python3からはreduce関数を使うためにはimportを書かないといけないとのことです。

1
2
3
4
5
6
7
from functools import reduce

in_data = [1, 2, 3]

out_data = reduce(lambda x, y: x + y, in_data)

print(out_data) # 出力 6

上記は1+2した結果にさらに3を足して6になる・・・ということらしいです。

reduceの第3引数には下記のように初期値を設定することができます。

1
2
3
4
5
6
7
from functools import reduce

in_data = [1, 2, 3]

out_data = reduce(lambda x, y: x + y, in_data, 10)

print(out_data) # 出力 16

初期値10に1足して、それに2足して、最後に3を足して16となります。
実務処理で私はこの関数を使ったことがありません。。。ですが、機械学習とかで便利なことがあるのかもしれません・・・タブン。

(Google Colaboratoryで動作確認しています。)