sorted の key 引数でカスタムソート

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

sorted の key 引数でカスタムソート とは

sorted の key 引数で複雑なソートをシンプルに書く方法を学びます。本レッスンでは、sorted の key 引数でカスタムソート の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

sorted の key 引数でカスタムソート

Python の sorted 関数は 強力な万能ソート。数値や文字列ならそのまま昇順に並べてくれますが、本当の真価は key 引数 にあります。sorted(iterable, key=関数) と書けば、各要素を関数で変換した値 でソートしてくれる、これが今回のテーマです。タプルのリスト、辞書のリスト、文字列の長さ順、絶対値順、複数キーの組み合わせ、key を使えばどれも 1 行。SQL の ORDER BY に近い感覚で書ける、Python の名作 API のひとつです。

sorted新しいリスト を返し、元のリストを破壊しません。元のリストを直接書き換えたいときは list.sort() を使います。

key 引数は Python 屈指の便利機能。一度覚えれば、生のループでソートを書きたくなることはほとんどなくなるはずです。

基本のおさらい

まずは引数なしの sorted をおさらいしておきます。下記のとおりです。

Python

nums = [3, 1, 4, 1, 5, 9, 2, 6] print(sorted(nums)) # [1, 1, 2, 3, 4, 5, 6, 9] print(sorted(nums, reverse=True)) # [9, 6, 5, 4, 3, 2, 1, 1]

reverse=True で降順、key を指定すれば任意の基準。これだけで日常のソートはほぼカバーできます。

key 引数とは?

key には 「要素を引数に取り、比較に使う値を返す関数」 を渡します。sorted は内部で各要素に key を適用し、その結果を基準に並べ替えます。

Python

words = ["python", "go", "javascript", "c"] print(sorted(words, key=len)) # ['c', 'go', 'python', 'javascript']

len を渡すだけで「短い順」のソートが完成。key=lenlen は関数オブジェクトを渡している、ということに気付けると、Python の 高階関数 の理解が一段深まります。

lambda と組み合わせる

組み合わせの黄金パターンが key=lambda x: ...。一回しか使わない短い関数なら lambda で書くのが Python の常套手段です。

Python

users = [ {"name": "Taro", "age": 30}, {"name": "Hanako", "age": 25}, {"name": "Jiro", "age": 40}, ] by_age = sorted(users, key=lambda u: u["age"]) print(by_age[0]) # {'name': 'Hanako', 'age': 25}

lambda u: u["age"] で「各 dict から age を取り出す」関数を作り、それを key に渡しています。年齢順 のソートが 1 行で完了する、これが Python の表現力です。

動きを追ってみる

diagram (will load when visible)

図のように、key比較値を計算 → 並べ替え → 元の要素を新しい順に返す、という流れ。元の要素自体は加工されません。例えば key=str.lower でソートしても、結果のリストには元の大文字小文字のまま残ります。

複数キーで並び替える

key にタプルを返す関数を渡せば、複数キーのソート ができます。SQL の ORDER BY a, b と同じ感覚です。

Python

students = [ {"name": "A", "grade": 2, "score": 80}, {"name": "B", "grade": 1, "score": 90}, {"name": "C", "grade": 1, "score": 70}, ] result = sorted(students, key=lambda s: (s["grade"], -s["score"])) print(result[0]) # {'name': 'B', 'grade': 1, 'score': 90}

(grade 昇順, score 降順)(s["grade"], -s["score"]) で表現。- を付けることで降順を模倣しています。reverse=True は全体に効くので、片方だけ反転したいときはこのテクニックを覚えておきましょう。

よくある間違い

  1. key に関数を 呼び出した結果 を渡してしまう。sorted(words, key=len(words)) は誤り、sorted(words, key=len) のように関数自体を渡します。
  2. keycmp を混同する。Python 3 では cmp は廃止され、key だけが残っています。古い記事に注意。
  3. sorted はミュータブルな操作ではなく 新しいリストを返す。元データを変更したいなら lst.sort() を選択しましょう。

sorted安定ソート。同じキーを持つ要素同士は、元の順序が保たれます。これを使えば「先に第二キーで並べてから、第一キーで並べる」というテクニックも可能です。

やってみよう

単語リスト words を受け取り、文字数の昇順 で並べたリストを返す関数 sort_by_length を書いてみましょう。sorted(words, key=len) で書けば 1 行で済みます。key の威力を体感してみてください。同じ文字数の単語は元の順番が保たれることも、安定ソートのおかげで保証されます。

よくある質問

Q. このトピックは Python 以外の言語でも同じ書き方ですか?

A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。

Q. 実行してエラーが出た場合の対処は?

A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。

Q. 次のステップで何を学ぶべきですか?

A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。

次のレッスン

次は set で重複を除去する で、sorted の key 引数で複雑なソートをシンプルに書く方法を学びます を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. key でソート の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. key でソート とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. sorted を使って新しいリストを返す
  2. key=len で文字数順に並べる
  3. 元のリストを破壊しない

入出力例

test-cases.txt

sort_by_length(["python","go","javascript","c"])["c","go","python","javascript"] sort_by_length(["bb","aa","c"])["c","bb","aa"] sort_by_length(["hello"])["hello"] sort_by_length([])[]

ヒント

main.py
main.py
学習モード

メモ

sorted の key 引数でカスタムソート

⌘S で保存