【Python】sortを使ったリストの並べ替えをわかりやすく解説
はじめに
Pythonでリストの要素を並べ替える方法として、sort メソッドと sorted 関数があります。
たとえばデータを特定の順序に揃えたいときに非常に便利です。
初心者の皆さんにとっては「どう書けばいいの?」「何が違うの?」といった疑問を抱く場面も多いでしょう。
ここでは、これらの機能を使いこなすために必要な基礎知識を整理します。
また、実務での活用方法や複数条件での並べ替えなどにも触れます。
プログラミング未経験の方でも理解しやすいように、平易な言葉で解説を進めていきます。
この記事を読むとわかること
- sort メソッドと sorted 関数の基本的な違い
- 昇順・降順の切り替え方や、複数条件の並べ替え
- key 引数を使った柔軟なソート方法
- 実務における具体的な活用事例と注意点
- よくある疑問とトラブルシューティング
sortとsortedの違い
Pythonでは、リストに対して sort というメソッドが用意されています。
これを使うと、リスト自体を並べ替えることができます。
一方、sorted は引数として渡したデータを並べ替え、新たに整列済みのリストを返す関数です。
この違いは小さいようで重要です。
sortメソッドは「リストをその場で書き換える(破壊的変更)」のに対し、sorted関数は「新しいリストを返す(非破壊的変更)」という特性を持ちます。
特に複数の処理を並行して行う場合には、オリジナルのリストが上書きされてしまうかどうかで、プログラムの動きが大きく変わることがあります。
また、内部的に使われているアルゴリズムは同じため、並べ替えの速度や安定性に大きな差はありません。
そのため用途に応じて「手元のリストを直接変換するか」「新たにソート結果を受け取りたいか」という視点で選ぶのが一般的です。
リストを昇順・降順に並べ替える
多くのケースでは、数値や文字列を小さい(またはアルファベット順)から順番に並べたい場面が多いかもしれません。
こうした場合は、ごく簡単な記述だけで処理が可能です。
たとえば、整数が入ったリストを昇順に並べ替えるなら、以下のように書きます。
numbers = [5, 2, 9, 1, 7] numbers.sort() # 昇順にソート print(numbers) # [1, 2, 5, 7, 9]
もし降順に並べ替えたい場合は、sort メソッドや sorted 関数の引数に reverse=True
を指定します。
numbers = [5, 2, 9, 1, 7] numbers.sort(reverse=True) print(numbers) # [9, 7, 5, 2, 1]
なお、リストが文字列の場合でも使い方は同じです。
昇順はアルファベット順、降順はその逆になるので、自分の目的に応じて reverse=True
の有無を決めると良いでしょう。
ソートで使われるアルゴリズム
Pythonのリストを並べ替えるメカニズムは、多くの場合でTimsort(ティムソート)と呼ばれるアルゴリズムに基づいています。
このアルゴリズムは安定性と効率の両立を図っており、実務レベルでも十分にスピードと扱いやすさを期待できます。
アルゴリズムの詳細を知らなくても、基本的には list.sort()
や sorted()
を使うだけで高速な並べ替えが可能です。
ただし、大規模なデータを扱う場面では、その仕組みをある程度理解しておくと性能の見積もりがしやすくなるでしょう。
たとえば、最悪の場合でも O(n log n) の計算量がかかることは知っておくと便利です。
安定ソートであるため、同じ値を持つ要素同士の順番は保持されます。
これは特に複数条件での並べ替えを行う際に大きな利点となります。
sortの基本的な書き方と動作
sortメソッドを使うときは、単純に リスト.sort()
と書きます。
このとき、リスト自体がソート後の順序に書き換わります。
何度も同じリストを作り直さなくていいので、処理をシンプルにしたい場合には便利です。
しかし、sortを実行した後のリストは元の順番に戻せません。
もとの順番を残しておきたいときは、別の変数にあらかじめコピーをとっておくか、sorted 関数を利用するのがおすすめです。
以下は例として、文字列のリストを並べ替えているコードです。
簡潔なケースですが、イメージをつかみやすいでしょう。
fruits = ["banana", "apple", "cherry", "date"] fruits.sort() print(fruits) # ['apple', 'banana', 'cherry', 'date']
上書きが行われるので、後の処理で元の順序が必要な場合は注意してください。
sortで複数条件を扱う方法
複数条件での並べ替えが必要になる場面では、基本的に安定ソートの考え方を活用します。
まず第一条件で並べ替えを行い、その結果に対して第二条件の並べ替えをかけるというステップを踏むと、第一条件での順序関係を崩さずに二段階のソートができます。
例えば、映画のデータを「年代の古い順」に並べ、同じ年代の中は「タイトルのアルファベット順」で並べたい場合を考えます。
まずは映画の年代でsortし、そのあとにタイトルの順序でsortすると、年代が同じ映画の順番だけが更新されるわけです。
Pythonのsortは安定ソートなので、初回のソート結果を維持しながら二度目のソートが可能です。
以下のようなイメージで実装できます。
movies = [ {"title": "MovieC", "year": 1999}, {"title": "MovieA", "year": 1999}, {"title": "MovieB", "year": 2001}, {"title": "MovieD", "year": 2001}, ] # 年代順で昇順 movies.sort(key=lambda x: x["year"]) # 同じ年代内ではタイトルで昇順 movies.sort(key=lambda x: x["title"]) print(movies) # 年代が1999, 1999, 2001, 2001の順で、タイトルはアルファベット順に整列
実務では、データを何度か段階的に整列するケースも考えられますが、こうしたやり方を応用すれば柔軟に扱えます。
ソート後の要素を取得する方法
sortメソッドを呼んだあとのリストは、すでに整列済みの状態になっています。
そのまま print()
したり、スライスで先頭のn件を取り出すなどの操作が可能です。
たとえば、並べ替えたあとで最初の3つの要素だけを使いたい場合は、以下のように書きます。
numbers = [3, 8, 1, 2, 10] numbers.sort() top_three = numbers[:3] print(top_three) # [1, 2, 3]
よくあるケースとして、並べ替えたあとの最大値や最小値を取りたい場合もあります。
その場合は numbers[-1]
や numbers[0]
で簡単にアクセスできます。
sortedで新しいリストを取得する方法
一方で sorted 関数は、元のリスト(あるいはタプルや文字列など)を変更せずに、新しいリストを返してくれます。
このため、オリジナルのデータをそのまま保持しておきたい場面で便利です。
numbers = [3, 8, 1, 2, 10] sorted_numbers = sorted(numbers) print(numbers) # [3, 8, 1, 2, 10] print(sorted_numbers) # [1, 2, 3, 8, 10]
このように、sortedを使うと元の numbers
はそのままの順序を保ち、sorted_numbers
にだけ昇順で並べ替えられた結果が格納されます。
sorted()
も引数に reverse=True
を指定できるので、降順を生成するのも簡単です。
key引数で独自の基準を指定する
単純に数値を昇順や降順に並べるだけでなく、特定の条件やカスタムロジックを使って並べ替えることがあります。
たとえば文字列の長さでソートしたり、辞書型の特定のキーに注目してソートしたりといったケースです。
このとき役立つのが key
引数です。
以下は、文字列のリストを「文字数の少ない順」に並べ替える例です。
words = ["apple", "date", "banana", "kiwi"] words.sort(key=len) print(words) # ['kiwi', 'date', 'apple', 'banana']
key=len
のように記述すると、sortの内部で要素ごとに len
関数を実行した結果をもとに並べ替えが行われます。
もし複雑なロジックが必要であれば、lambda
関数や別途定義した関数を指定するのもよくある書き方です。
# 各単語の末尾の文字(最後のアルファベット)を基準にソートする words = ["apple", "date", "banana", "kiwi"] words.sort(key=lambda x: x[-1]) print(words) # ['banana', 'apple', 'date', 'kiwi'] (末尾の文字順に並ぶ)
こうした方法を覚えておくと、実務のデータ整理でも応用しやすくなります。
実務での活用例: ユーザー情報の並び替え
ここからは、もっと現場に近い形での例を紹介します。
たとえばユーザー情報をリスト化し、「年齢が若い順」に並べたい場合を考えましょう。
ユーザー情報は以下のような辞書型のリストだとします。
users = [ {"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}, ]
このリストを年齢順に並べるには、先ほどの key
引数を活用します。
users.sort(key=lambda user: user["age"]) print(users) # [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
ユーザーの並べ替えが必要なシーンでは、たとえば会員登録日や購入金額、ログイン頻度などを基準に並べることもあります。
Pythonのsortやsortedなら、どんな切り口でも key=
による柔軟なソートが可能です。
こうした機能は管理ツールや分析ツールを作る際に重宝します。
実務での活用例: 売上データの分析
別の例として、売上データのリストがあるとします。
たとえば各商品の「名前」と「売上個数」を辞書型でまとめておき、その合計を週ごとや月ごとに集計するといったケースを考えましょう。
このとき、多く売れている順番に商品を表示したいときは、key
引数に「売上個数(あるいは金額)」を指定し、さらに reverse=True
で降順にソートします。
sales_data = [ {"product": "Pen", "quantity": 120}, {"product": "Notebook", "quantity": 60}, {"product": "Marker", "quantity": 150}, ] # 売上個数の多い順に並べ替え sales_data.sort(key=lambda x: x["quantity"], reverse=True) print(sales_data) # [{'product': 'Marker', 'quantity': 150}, {'product': 'Pen', 'quantity': 120}, {'product': 'Notebook', 'quantity': 60}]
こうすることで、分析レポートなどにも活用しやすいデータ構造を作れます。
在庫管理やランキング表示といった処理でも、同様の手順が役立ちます。
カスタム関数で柔軟なソートを実現
ときには key
引数の中で単純な値比較ではなく、複雑な変換を行ってから並べ替えたい場合もあります。
たとえば、商品名の特定部分を数値に変換して基準にする、などです。
こうしたケースでは、カスタム関数 を作り、key=その関数
という形で指定すればOKです。
以下のようなイメージです。
def custom_sort_key(item): # "ItemXYZ" の "XYZ" の部分を数値として扱いたい例 name_part = item["name"][4:] # 先頭4文字 "Item" を除去 return int(name_part) items = [ {"name": "Item100", "stock": 10}, {"name": "Item20", "stock": 5 }, {"name": "Item3", "stock": 12}, ] items.sort(key=custom_sort_key) print(items)
ここでは、name
の文字列中に含まれる数字を取り出して比較しています。
こうしたアプローチにより、ソートの柔軟性は格段に上がります。
ソート時に気をつけたいエラーと対処法
Pythonのsortは、要素の間で比較ができないケースではエラーを起こすことがあります。
たとえば、リスト内に文字列と数値が混在していると、単純には比較できずにエラーになるでしょう。
実務でデータが入り混じってしまうケースはそれほど珍しくありません。
こうした場合は、比較が成立するように型をそろえるか、無理にソートしようとしないように設計する必要があります。
もしデータ内の一部だけをソートの対象にしたいのであれば、たとえば「数値データだけを抽出した新しいリスト」を作ってからsortする方法が有効です。
あるいは、「文字列として解釈してから比較する」ような変換処理をカスタム関数で行っても良いでしょう。
安定ソートのメリット
ここで改めて、Pythonのソートが安定ソートであることのメリットに触れます。
先ほども解説したように、安定ソートでは同じ値を持つ要素の順序が変わりません。
これにより「第一条件でsortしたあと、第二条件でsortする」といった方法で段階的な並べ替えが可能になるのです。
また、一度目のソート結果に意味のある並びが含まれている場合(たとえば登録日の新しい順など)に、二度目のソートを別の基準でかけても最初の情報が崩れません。
複数の基準をもつデータを並べ替える際は、安定ソートが大きく役立ちます。
複数の並べ替え基準があるときは、安定ソートであるPythonのsortを段階的に実行する方法を覚えておくと便利です。
違うデータ型をまとめて並べ替えられるのか
実務では、リスト内に整数・文字列・タプル・辞書などが混在するケースも考えられます。
しかし、Pythonのsortやsortedは、基本的には「比較可能な型同士」でのみ並べ替えができます。
整数と文字列が混ざっていると、直接比較ができずエラーが発生します。
もしどうしても混在データをまとめてソートしたい場合は、比較に用いる共通の仕組み を作る必要があります。
たとえば、すべての要素を文字列に変換してからソートする、あるいは共通の評価関数を定義するなどです。
そうした変換ロジックを key
引数やカスタム関数に組み込めば、ある程度は対応できます。
ただし、データ型が入り乱れるとバグの温床にもなりやすいです。
使う側にとって分かりやすい構造になるよう、データ設計を見直すことが大切です。
よくある疑問とトラブルシューティング
初心者の方がsortやsortedを使う上で、戸惑うポイントはいくつかあります。
以下によくある疑問をまとめました。
ソート後にリストの要素が消えてしまったように見える
実は見えなくなるのではなく、思わぬ順序に再配置された結果、狙った要素を探しにくくなったケースが多いです。
特定の並べ替え結果を想定しているなら、key引数やreverse引数の設定を再確認しましょう。
タプルはsortできるの?
タプルはメソッドとしてのsortを持ちませんが、sorted関数を使うと新しいリストとして並べ替えが可能です。
辞書全体をsortしたらエラーになる
何を基準に比較するのかが定義されていないためです。
key=lambda x: x["キー名"]
のようにして、並べ替える根拠を指定してください。
大文字小文字を区別せずソートしたい
key=str.lower
のように指定することで、大文字・小文字を区別しない並べ替えができます。
たとえば words.sort(key=str.lower)
とすると、"Apple" と "apple" を同じ基準で並べ替えられます。
まとめ
Pythonでリストを並べ替える方法としては、sort メソッドと sorted 関数が基本になります。
どちらも同じアルゴリズム(Timsort)を使うため速度は遜色ありませんが、リスト自体を変更するか、まったく新しいリストを生成するかという点に違いがあります。
実務の現場では、ユーザー情報や売上データなど、並べ替えを活用したいシーンが多く存在します。
特に key
引数と安定ソートの仕組みを組み合わせることで、複数基準を使った並べ替えが簡単に実現できます。
一方で、Pythonのsortは比較ができないデータ型同士を並べ替えようとするとエラーになります。
データが複雑になるほど、基準を明示的に決めることが重要です。
初心者の皆さんはまずは単純なリストで練習し、慣れてきたら key
による拡張的な使い方や複数条件の活用を試してみてはいかがでしょうか。
最終的には、自分の作りたいプログラムに合わせて自由に並べ替えができるようになると、データ処理の幅がさらに広がるでしょう。
ぜひ覚えてみてください。