使用Version:Python 3.11.2
公式ドキュメント:ソートのテクニック
https://docs.python.org/ja/3/howto/sorting.html
概要
下記配列に対して様々なソートを実行する
testsheet = [
['Matt', 23, 80 ],
['Zill', 55, 46 ],
['May', 70, 90 ],
['May', 70, 80 ],
['Tyler', 55, 70 ],
['Tomothy',55, 70 ],
['太郎', 55, 70 ],
['はるか', 40, 70 ],
['$imon', 40, 70 ],
['ωatson', 40, 70 ],
['Tomothy',43, 80 ]
]
リストの出力例
for e in result: # resultはソート後のリストを指す
print(*e, sep=',')
Lv1 sorted関数
sorted()
またはsort()
を使う ことで多重キーでのソートが可能
result = sorted(testsheet)
- 1番目の要素、2番目の要素、3番目の要素、(略)、の順で優先的に昇順ソートする
- 文字列はUnicodeコードに基づいてソートされる
-
sorted()
- 組み込み関数
- 「ソートした新たなリスト」を生成する
-
sort()
- リスト型のメソッド
- 「元のリスト」をソートする
文字のUnicodeコードを確認する際はord関数を用いる
for e in result:
print('0x%04X'%(ord(e[0][0])))
下記でも同様のソート処理が可能(詳細後述)
result = sorted(testsheet, key=lambda x:(x[0],x[1],x[2]), reverse=False)
Lv2 降順ソート
reverseパラメータを指定する ことで昇順または降順の指定が可能
# 全要素を降順でソートする
result = sorted(testsheet, reverse=True)
下記でも同様のソート処理が可能(詳細後述)
result = sorted(testsheet, key=lambda x:(x[0],x[1],x[2]), reverse=True)
result = sorted(testsheet, key=lambda x:(-x[0],-x[1],-x[2]))
Lv3 ソートキーの指定
key
パラメータに関数を指定する ことでソートキーを定義できる
たとえば以下のようにソートする場合を考える
- "名前"、"国語"をキーに昇順ソートする
- "数学"をキーにはしない
この条件について以下のようにラムダ式で記述できる
result = sorted(testsheet, key=lambda x:(x[0],x[1]))
Mayさん行の順番については公式ドキュメントにおいても言及されている
ソートは、 安定 (stable) であることが保証されています。これはレコードの中に同じキーがある場合、元々の順序が維持されるということを意味します。
Lv4 昇順と降順の併用
key
パラメータにてマイナスを付けることで降順ソートが可能
たとえば「国語を昇順、数学を降順に並べたい」場合には下記のように定義する
result = sorted(testsheet, key=lambda x:(x[1],-x[2]))
国語の点数が同点になったら数学の点数で降順に並べられていることがわかります。
Lv5 任意の優先度
単純な昇順降順にとどまらず独自の優先度を持ち込むことも可能
key
パラメータに別途関数を指定する ことで「■カスタムソート、■数学で降順ソート、■名前で昇順ソート」のような処理を実現できる
# 贔屓生徒リスト
favsheet = ["はるか","May","Zill"]
# 贔屓レベルを出力する関数。値が低いほど贔屓度が高いものとする
#(はるか(0) > May(1) > Zill(2) > その他大勢(3) の順に贔屓する)
def get_fav_index(x):
for i, name in enumerate(favsheet):
if name == x[0]:
return i
return len(favsheet)
'''
別の書き方
get_fav_index = lambda x:\
[i if name == x[0] else len(favsheet) for i, name in enumerate(favsheet)]
'''
# 贔屓ソート、数学で降順ソート、名前で昇順ソート
result = sorted(testsheet, key=lambda x:(get_fav_index(x),-x[2],x[0]))
独自の優先度とはいえ結局は数値を返すような関数を利用することになる
そのため最終的には昇順または降順でのソートに帰結する