Developer

【Python連載】sort、map、filter関数でラムダ式を利用する
2021.12.27
Lv1

【Python連載】sort、map、filter関数でラムダ式を利用する

Pythonは、オブジェクト指向と呼ばれるプログラミング言語の一つです。
ラムダ式は、簡単な処理ならば1行で簡潔に記述することが出来ます。
ラムダ式を利用してコードを効率的に出来る場面は、多々あります。
今回は、ラムダ式を利用すれば便利になる例をいくつか紹介します。


sort()でラムダ式を利用する

リストの要素を並べ替えるものにsort()というものがありました。
このsort()、並べ替えの際にどのような基準で並べ替えを行うかをkey引数を通して関数で指定することが出来ます。
その関数部分はdef文で定義した関数以外にも、ラムダ式で直接指定することが出来ます。
一旦、ラムダ式を用いないパターンで記述したものが以下となります。

#並べ替え用の比較関数を定義
def compare_rank(item):
    rank_list = ["C","B","A","S","SS"] #C~SSという順番で並べ替える
    postion = rank_list.index(item)    #渡されたitemのインデックス番号を取得
    return postion                     #インデックス番号を返す

data = ["A","C","SS","A","B","SS","S","C"] #並び替え対象のリスト
data.sort(key = compare_rank)              #compare_rankからの戻り値を元にソートされる
print(data)
C:\Python> python 12-3-1.py
[‘C’, ‘C’, ‘B’, ‘A’, ‘A’, ‘S’, ‘SS’, ‘SS’]

ランキング等でよく使われるようなランクをイメージしてください。
ランクが不揃いに並んでいるものを、CからSSランクまでを順番に並べ替えてみました。

では、これをラムダ式を用いて記述してみます。

rank_list = ["C","B","A","S","SS"]         #C~SSという順番で並べ替える
data = ["A","C","SS","A","B","SS","S","C"] #並び替え対象のリスト

data.sort(key = lambda item : rank_list.index(item)) #比較関数をラムダ式で記述
print(data)
C:\Python> python 12-3-2.py
[‘C’, ‘C’, ‘B’, ‘A’, ‘A’, ‘S’, ‘SS’, ‘SS’]

関数定義部分が無くなったため、コードとしてはスッキリしましたね。

map()でラムダ式を利用する

map()はリスト等から順に要素を取り出して、それを引数として指定した関数を実行します。
様式は次の通りです。

map(関数, イテラブル)
※イテラブルとは、リストやタプルや辞書などのfor文で繰り返せるオブジェクトのことでした

それでは、例を見てみましょう。
まず、ラムダ式を用いないパターンで記述したものが以下となります

#関数の定義
def squaring(i):
    return i ** 2       #2乗した値を返す

num_list = [1,2,3,4,5]
squaring_num_list = list(map(squaring, num_list)) #num_listから取り出した値が関数squaringで2乗され、list()でリスト化
print(squaring_num_list) 
C:\Python> python 12-3-3.py
[1, 4, 9, 16, 25]

num_listから順次取り出された値が関数squaringで2乗され、戻った値はlist()でリスト化されます。

ではこれを、ラムダ式で記述してみます。

num_list = [1,2,3,4,5]
squaring_num_list = list(map(lambda i : i ** 2, num_list)) #関数部分をラムダ式で記述
print(squaring_num_list)
C:\Python> python 12-3-4.py
[1, 4, 9, 16, 25]

map()の場合と同様に、コードがスッキリしました。

filter()でラムダ式を利用する

filter()は、関数で指定した条件に沿ってリスト等から要素を取り出します。
次の例では、num_listから3より大きい値だけを取り出してリスト化しています。

#関数の定義
def filtering(x):
    if(x > 3):
        return True
    else:
        return False

num_list = [1,2,3,4,5]
filtering_num_list = list(filter(filtering, num_list)) #num_listから取り出した値を関数filteringでフィルタリング、list()でリスト化
print(filtering_num_list) 
C:\Python> python 12-3-5.py
[4, 5]

これをラムダ式で記述する場合には、if文の部分を次のように省略することが可能です。

num_list = [1,2,3,4,5]
filtering_num_list = list(filter(lambda x : x > 3, num_list)) #関数部分をラムダ式で記述
print(filtering_num_list) 
C:\Python> python 12-3-6.py
[4, 5]

以上、ラムダ式を利用すれば便利にコードを記述出来る例のご紹介でした。
引数として定義された関数を渡すパターンだけではなくラムダ式で直接記述するパターンもある、ということを頭の中に入れておきましょう。

最後に、ラムダ式はコードが簡潔に書けるということ以外にも、たんに関数が増えることを防げるという利点もあります。何度も使うような関数の場合はラムダ式ではなく普通に関数定義して使用する方が良いと思いますが、一度だけの場合にはラムダ式を使用した方がコードが全体的にスッキリします。
ただ最初からラムダ式を自分で書くのは難しいと思いますので、まずは一旦読めるようにだけなっておきましょう。


まとめ

sort()、map()、filter()などの引数に関数を指定するものは、ラムダ式で指定することも出来る。


確認問題

次のプログラムを実行しました。

num_list = [-5,1,-3,4,0,-2,5,-1,2,-4,3]
filtering_num_list = list(filter(lambda x : x > 0, num_list))
squaring_num_list = list(map(lambda x : x ** 2, filtering_num_list))
squaring_num_list.sort()
print(squaring_num_list) 

次の選択肢のうちから、正しい出力結果を選択してください。
(1)ラムダ式の記述が誤っているので、エラーが発生する
(2)[1, 16, 25, 4, 9] と出力
(3)[1, 4, 9, 16, 25] と出力
(4)[1, 4, 5, 2, 3] と出力

解答

まず2行目で、filter()で元のnum_listから0より大きい値でフィルタリングを行いリスト化します。
次に3行目で、map()でフィルタリングされたリストの各要素を2乗したものをリスト化します。
次に4行目で、sort()でリストの各要素を昇順で並べ替えます。sort()は引数に何も指定しない場合は各要素の値を昇順で並べ替えます。

よって、答えは(3)の[1, 4, 9, 16, 25]になります。


前回の確認問題の解答例

前回の問題は、以下の通りです。

次のプログラムを実行すると、エラーが発生します。

lambda_sample = lambda x=1,y=2,z=3 : sam = x + y + z , print(sam)
lambda_sample()

エラーの原因について、次の選択肢のうちから正しい記述を選択してください。
(1)ラムダ式では、引数は2つまでしか指定出来ない
(2)実行する処理は、加減乗除等の計算しか行うことは出来ない
(3)実行する処理が、単一の処理となっていない
(4)ラムダ式では、引数に初期値を設定することはできない

ラムダ式では、引数は複数取ることが可能で、また引数に初期値を与えることが出来ます。また、加減乗除以外にもメソッドも用いることも出来ます。ただし、一行で済むような単一の処理しか行うことが出来ません。
よって正解は(3)となります。

連載目次

独学で学ぶ Pythonプログラミング 連載目次