29.ソート

ソートはデータを並べ替えを行います。

プログラムの中ではかなり多く用いられる処理です。

文字列型の並び替え

インデックスを用いて文字列を逆さまにすることができます。

In [1]:
a1 = 'abcdeアイウエオ123幹事!'
# [::-1]で逆さまにする
print(a1[::-1])
!事幹321オエウイアedcba

文字列内で使われている文字を並び替えるには
一旦リスト型に変換してから並び替えし、文字列に戻すことで
文字列の並び替えを実現できます。

sorted関数を使うと、文字列を分割して並び替えを行います。
第二引数のreverseにTrueを指定すれば降順
Falseを指定するか第二引数なしの場合は昇順となります。

In [2]:
a2 = 'abcdeアイウエオ123幹事!'
# sorted関数でリストに変換して昇順ソート
print(sorted(a2,reverse=False))

# sorted関数でリストに変換して降順ソート
print(sorted(a2,reverse=True))
['!', '1', '2', '3', 'a', 'b', 'c', 'd', 'e', 'ア', 'イ', 'ウ', 'エ', 'オ', '事', '幹']
['幹', '事', 'オ', 'エ', 'ウ', 'イ', 'ア', 'e', 'd', 'c', 'b', 'a', '3', '2', '1', '!']

join関数を用いるとリスト型のものを1つづつ連結して
文字列にすることができます。

In [3]:
a3 = 'abcdeアイウエオ123幹事!'

print(''.join(sorted(a3 , reverse=True)))
幹事オエウイアedcba321!

あまり文字列だけでの並び替えは
使う機会がないかもしれませんが、いざという時に役立つ手法です。

リスト型のソート

リスト型の関数であるsort関数を使う方法

昇順:
変数名.sort()

降順:
変数名.sort(reverse=True)

sorted関数を用いる方法

昇順:
sorted(変数名)

降順:
sorted(変数名,reverse=True)

※sorted関数は元のリストの並び順に影響しないが
sort関数はリストの並び替えを行い、リスト型の並び順が変わる。

In [4]:
lis1= [3,1,2,4,5,7,6]
print(lis1)

# 昇順ソート
print(sorted(lis1))

# sorted関数の後に再度呼び出しても順番は変わら無い
print(lis1)
[3, 1, 2, 4, 5, 7, 6]
[1, 2, 3, 4, 5, 6, 7]
[3, 1, 2, 4, 5, 7, 6]
In [5]:
lis2= [3,1,2,4,5,7,6]
print(lis2)

# 降順にソート
lis2.sort(reverse=True)
# sort関数の後に呼び出すと順番は変わる
print(lis2)
[3, 1, 2, 4, 5, 7, 6]
[7, 6, 5, 4, 3, 2, 1]

順番がプログラムに大きな影響を与える場合は注意が必要

元の形を保持したままにするのか、並び替えてから使うのか
処理のさせ方を考えて使い分けをします。

辞書型のソート

辞書型の並び替えは
キーの昇順と降順
値での昇順と降順
この4通りが存在します。

キー昇順:sorted(dct.items())

値の昇順:sorted(dct.items(), key=lambda x:x[1])

キー降順:sorted(dct.items(), reverse=True)

値の降順:sorted(dct.items(), key=lambda x:x[1],reverse=True)

In [6]:
# キー昇順
dct = { 2:3, 3:4, 1:2, 0:8, 4:2 }
for k, v in sorted(dct.items()):
    print(k,':',v)
0 : 8
1 : 2
2 : 3
3 : 4
4 : 2
In [7]:
# キー降順
dct = { 2:3, 3:4, 1:2, 0:8, 4:2 }
for k, v in sorted(dct.items(), reverse=True):
    print(k,':',v)
4 : 2
3 : 4
2 : 3
1 : 2
0 : 8
In [8]:
# Value昇順
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }
for k, v in sorted(dct.items(), key=lambda x:x[1]):
    print(k,':',v)
1 : 2
4 : 2
2 : 3
3 : 4
0 : 8
In [9]:
# Value降順
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }
for k, v in sorted(dct.items(), key=lambda x:x[1],reverse=True):
    print(k,':',v)
0 : 8
3 : 4
2 : 3
1 : 2
4 : 2

lambdaというのはラムダと読み、
pythonでは無名の関数を表す予約語になります。

ラムダについては後の講義で詳しくやって行きたいと思いますので、
ここでは割愛しますが、辞書の値で並び替えするには、
こういった書き方をしなくてはいけません。

辞書型そのものは並び順が大きな意味を持たないデータ型であるので
それを使うときにだけ並び替えを行うのが一般的です。

例えば、最終的に上位1番だけを出力する
といった時には降順で並び替えて出力する、ということを行います。

In [10]:
dct = { 2:'3', 3:'4', 1:'2', 0:'8', 4:'2' }

# まず辞書を値の降順ソートしてからenumrate関数に組み込む
for i , d  in enumerate(sorted(dct.items(), key=lambda x:x[1],reverse=True)):
    if i>=1:
        # 2回目で処理を抜ける
        break
    print(i,d[0],d[1])
0 0 8

繰り返しの処理を行う際にまず、辞書を値の降順でソートしておきます。
enumerate関数から返されるカウント数をみて繰り返しの処理を抜けます。

そうすることでデータが大量にある際に、上位何番まで出力するといった
ことも実現できるようになります。

注意点としてはenumerate関数と辞書型のitemsを使うと、返ってくるデータ型は
数値型とタプル型なので気をつけてください。

pythonではsorted関数を用いることで、
様々な形のデータの並び替えを行うことができます。

並びが重要なものを取り扱うプログラムを作るのに役立つと思います。