Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Pythonのsorted関数とkey引数のラムダ関数についての解説

Pythonでsorted関数のkeyにラムダ関数を使ってリスト要素などを並び替える方法の解説

Pythonでリスト要素などを並び替えるsorted()のkey引数にラムダ関数を設定して使う方法の入門レベルの解説

今回はPytyhonの組み込み関数のsorted()を、そのkeyパラメーターにラムダ関数を指定して使う場合の方法について簡単に解説します。

すなわち、以下のような形式のコードになる場合の解説です。

sorted(イテラブルオブジェクト, key=lambda~)  

前提知識:イテラブルオブジェクトとラムダ関数

イテラブルオブジェクトについての基本知識

今回の前提知識としてまずイテラブルオブジェクトについての知識が必要となりますが、それについては「【初心者にもわかりやすく】Pythonのイテレータについて、その基本とfor文の仕組みを解説」

の中で説明してあるので、ご覧ください。

ラムダ関数についての基本知識

また次にラムダ関数の知識も必要となりますが、それもすでに「【Python入門】lambda(ラムダ)関数とは?その基本ついてわかりやすく解説。メリットや注意点は?」で解説しましたので、そちらをご覧ください。

ラムダ関数とともにsorted()を使う方法

sorted()の基本的構文とオプション引数

さて、上述のようにPythonにもともと最初から用意されている関数(組み込み関数)のsorted()を、ラムダ関数とともに使う場合は次のような形式で使います。

sorted(イテラブルオブジェクト, key=lambda~)  

なお、sorted関数は本来以下の2つのオプション引数(書かなくても良いが、書けば有効になる引数)が存在します。

  • key引数(keyパラメータ)
  • reverse引数(reverseパラメータ:デフォルトではFalseとなる)

の2つです。

Python公式ドキュメントでは次のように説明されています。

key には 1 引数関数を指定します。これは iterable の各要素から比較キーを展開するのに使われます (例えば、 key=str.lower のように指定します)。 デフォルト値は None です (要素を直接比較します)。

reverse は真偽値です。 True がセットされた場合、リストの要素は個々の比較が反転したものとして並び替えられます。

Python公式ドキュメント

ですが今回は説明の便宜のために、reverse引数については無視します。

以上の説明から、keyには1つの関数を指定することになります。今回はそれにラムダ関数(無名関数)を指定する場合の解説です。

さて、さっそくイテラブルオブジェクトの1種であるリストオブジェクトを新しく作って、sorted()関数を使ってみましょう。

list=[
    ('apple', 100),
    ('orange', 150),
    ('strawberry', 300),
    ('avocado', 400),
]

果物とその値段のタプルを4つ作り、それらを要素とするリストを作りました。

ではまずは単純にsorted()だけを使って並び替えてみます。

sorted(list)

実行結果は、

[('apple', 100), ('avocado', 400), ('orange', 150), ('strawberry', 300)]

となります。果物名のアルファベット順に従って、リストの要素が並び替えられたことに着目してください。

このように、イテラブルオブジェクトだけを指定して、他に何も指定しない場合は、リストの要素となっているタプルのうち、それらの第1要素である果物について、アルファベット順に並ぶとわかりました。

これはプログラミングとは関係のない一般社会・日常生活でも普通は、何かを並び替えるときは、まずは「あいうえお順やアルファベット順」で並べようとするでしょうから、その日常生活の考え方がプログラミングでも反映されているわけですね。

では、次に「価格順」に並び替えてみましょう。つまり、実行結果として、

[('apple', 100), ('orange', 150), ('strawberry', 300), ('avocado', 400)]

このようになる並び替えを作ってみましょう。

そこでラムダ関数を使います。

key引数の要件

key引数については公式ドキュメントにおいて次のようにかかれています。

比較を行う前にリストの各要素に対して呼び出される関数 (または呼び出し可能オブジェクト) を指定するパラメータ

公式ドキュメント

そしてその関数(または呼び出し可能オブジェクト:__call__()メソッドをもっているオブジェクト)については、以下のような要件が指定されています。

key パラメータの値は関数または呼び出し可能オブジェクトであって、単一の引数をとり、ソートに利用されるキー値を返すものでなければいけません。

公式ドキュメント

大雑把にいえば要件は、

  • 関数または呼び出し可能オブジェクトであること
  • その引数は1つだけ(引数の単一性)

ですね。

これらの要件にあうよう、次のようにしてみました。

sorted(list, key=lambda x: x[1])

ラムダ関数は関数なので、key引数の要件のうち、関数でなければならないという要件に合致しています。

同時に、今回のラムダ関数自身の引数はxという文字1つだけですので、引数の単一性という要件にも合致します。

そして実際にこれを実行すると、

[('apple', 100), ('orange', 150), ('strawberry', 300), ('avocado', 400)]

という結果が得られます。価格順に並んでいますね。

コードの解説

このコードの仕組みの考え方は次のようになります。

まず、並び替えという動作をする前に何かと何かを比較する作業が絶対に必要となります。

そしてその比較をする作業の前に、比較の基準を決める必要があります。何の点に注目して比較するのかということですね。

今回は果物名ではなく「価格」という点について注目して、「価格の大小」関係という点を比較の基準として設定しました。それがラムダ関数の「x[1]」という部分です。

lambda x: x[1]

このラムダ関数が、まずリストの各要素ごとに順番に呼ばれて実行されます。そして次のようなイメージで処理が進んでいきます。すなわち、

リストの最初の要素は(‘apple’, 100)なので、そのタプルが引数xに代入されます。

x[1]は(‘apple, 100)[1]のこと。

(‘apple’, 100)[1]は、「100」(タプルの[1]要素は、2番目の要素です)

100が返される

リストの次の要素(‘orange’, 150)についても同じ処理が繰り返される。

以下略

このように処理が進む結果、100、150、300、400という価格の情報だけが集められ、それらの大小関係が決定される。

それらの大小関係が決定され、それに基づいて、リストの構成要素が並び替えられる。

という感じです。

プログラミングを学びIT業界へ転職するなら現役エンジニアから学べるプログラミングスクールTechAcademy [テックアカデミー]でオンライン講座を受講するのが良いと思います。1人で悩みながら学習を進めるよりもわかりやすく、費やす時間も少なく合理的・効率的に学習できるからです。

など各種の講座が用意されています。無料で体験できるテックアカデミー無料体験も用意されています。

愛を分かち合いましょう