1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】配列のさまざまなソート

Last updated at Posted at 2023-03-23

使用Version:Python 3.11.2

公式ドキュメント:ソートのテクニック
https://docs.python.org/ja/3/howto/sorting.html

概要

下記配列に対して様々なソートを実行する

testsheetリスト
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 ]
]

image.png

リストの出力例

for e in result: # resultはソート後のリストを指す
    print(*e, sep=',')

Lv1 sorted関数

sorted()またはsort()を使う ことで多重キーでのソートが可能

result = sorted(testsheet)
  • 1番目の要素、2番目の要素、3番目の要素、(略)、の順で優先的に昇順ソートする
  • 文字列はUnicodeコードに基づいてソートされる
  • sorted()
    • 組み込み関数
    • 「ソートした新たなリスト」を生成する
  • sort()
    • リスト型のメソッド
    • 「元のリスト」をソートする

image.png

文字の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)

下記のように全ての要素に対し降順でソートできる
image.png

下記でも同様のソート処理が可能(詳細後述)

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]))

実行例は下記の通り(Lv1とはMayさん行の並びが異なる)
image.png

Mayさん行の順番については公式ドキュメントにおいても言及されている

ソートは、 安定 (stable) であることが保証されています。これはレコードの中に同じキーがある場合、元々の順序が維持されるということを意味します。

Lv4 昇順と降順の併用

key パラメータにてマイナスを付けることで降順ソートが可能
たとえば「国語を昇順、数学を降順に並べたい」場合には下記のように定義する

result = sorted(testsheet, key=lambda x:(x[1],-x[2]))

国語の点数が同点になったら数学の点数で降順に並べられていることがわかります。
image.png

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]))

これにより贔屓された3名(4名)が表の上に来る
image.png

独自の優先度とはいえ結局は数値を返すような関数を利用することになる
そのため最終的には昇順または降順でのソートに帰結する

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?