sorted の key 引数でカスタムソート
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=len の len は関数オブジェクトを渡している、ということに気付けると、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 の表現力です。
動きを追ってみる
図のように、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 は全体に効くので、片方だけ反転したいときはこのテクニックを覚えておきましょう。
よくある間違い
keyに関数を 呼び出した結果 を渡してしまう。sorted(words, key=len(words))は誤り、sorted(words, key=len)のように関数自体を渡します。keyとcmpを混同する。Python 3 ではcmpは廃止され、keyだけが残っています。古い記事に注意。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 つができることを確認しましょう。
- key でソート の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. key でソート とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
sortedを使って新しいリストを返すkey=lenで文字数順に並べる- 元のリストを破壊しない
入出力例
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([]) → []