リストの要素をソート(並び替え)する方法です。
リストは、数値や文字列を自由に登録できる便利な配列なので、 2つの方法で要素の並び替えをマスターしましょう。
- 組み込み関数sorted()を使う方法
- リスト型のメソッドlist.sort()を使う方法
リスト
リストは、自由に要素の追加や削除、入れ替えなどができます。
数値や文字列などを入れることができ、混ざっていても大丈夫です。
L_123 = [1, 2, 3] # 整数の数値
L_blank = [] # 空
L_str = ['あ', 'い', 'う'] # 文字列
L_mix = ['1', 2, '10'] # 数値と文字列が混在
タプル
リストと同じような配列に、タプルがあります。
名前 | 記述 | 要素の更新 |
リスト | [要素, 要素, 要素] # 角括弧 | 可 |
タプル | ( 要素, 要素, 要素 ) # 丸括弧 | 不可 |
リストは角括弧、タプルは丸括弧で要素を登録します。
タプルは、要素の更新ができないので、自身のソートはできません。
sorted関数でソート
リストは、組み込み関数sorted()でソートできます。
sorted(*, key=None, reverse=False)
sorted関数は、元のリストはそのままで、新たにソートしたリストを返します 。
before = [2, 4, 0, 5, 1]
after = sorted(before)
print('before: ', before)
print('after : ', after)
before: [2, 4, 0, 5, 1]
after : [0, 1, 2, 4, 5]
beforeに変化はなく、afterにはbeforeが昇順にソートされたリストが入っています。
文字列のソート
sorted関数は、文字列のソートができます 。
アルファベットのソートは、アルファベット順です。
先に大文字の文字列をソートし、その後で小文字の文字列をソートします。
sorted("I have a pen And an apple".split())
['And', 'I', 'a', 'an', 'apple', 'have', 'pen']
日本語のソートは、ひらがな、カタカナ、漢字の順です。
sorted("吾輩 は ネコ で ある".split())
['ある', 'で', 'は', 'ネコ', '吾輩']
keyパラメーターの使い方
keyパラメーターには、2つの使い方があります。
- ソートに利用する各要素に対して関数を呼び出す
- ソートに使用するキー列を指定する
ソートに利用する各要素に対して関数を呼び出す
数字の文字列をソートします。
数字の文字列は、数値としての大小ではなく、左から1文字ずつ比較します。
before = ['2', '02', '10', '3', '1']
after = sorted(before)
print('before: ', before)
print('after : ', after)
before: ['2', '02', '10', '3', '1']
after : ['02', '1', '10', '2', '3']
’02’の左から1文字目の’0’が最も小さく、’10’の左から1文字目の’1’は、’2’より小さいため、afterのようにソートされます。
数値としての大小でソートするときは、beforeを数値に変換してからソートします。
before = ['2', '02', '10', '3', '1']
after = sorted(before, key=int)
print('before: ', before)
print('after : ', after)
before: ['2', '02', '10', '3', '1']
after : ['1', '2', '02', '3', '10']
key=intとパラメーターを設定したことで、beforeを整数に変換する関数が呼び出されました。
関数は、自由に作ることができます。
3で割った余り(剰余)でソートします。
def mod(x):
return x % 3 # 3で割った余りを返す関数
before = [2, 4, 0, 5, 1]
after = sorted(before, key=mod) # beforeの各要素が、関数modを呼び出す
print('before: ', before)
print('after : ', after)
before: [2, 4, 0, 5, 1]
after : [0, 4, 1, 2, 5]
beforeの要素 | 余り(剰余) |
2 | 2 |
4 | 1 |
0 | 0 |
5 | 2 |
1 | 1 |
余りが小さい順にソートし、余りが同じときは元のリスト順になります。
key関数は文字列のソートにも使用できます。
アルファベットを小文字に変換してソートします。
sorted("I have a pen And an apple".split(), key=str.lower)
['a', 'an', 'And', 'apple', 'have', 'I', 'pen']
アルファベットの大文字と小文字の区別なくソートできました。
文字列の長さ(文字数)でソートします。
sorted("I have a pen And an apple".split(), key=len)
['I', 'a', 'an', 'pen', 'And', 'have', 'apple']
文字数が少ない順にソートし、文字数が同じときは元のリスト順になります。
ソートに使用するキー列を指定する
二次元配列をソートします。
二次元配列は、リストの中にリストがあります。
内にあるリストの要素から1つを指定してキー列にします。
デフォルトでは、最初の等しくない要素でソートします。
before = [[3, '2ch', 'NHK Eテレ東京'], [1, '8ch', 'フジテレビ'], [2, '4ch', '日テレ'] ]
after = sorted(before)
print('before: ', before)
print('after : ', after)
keyパラメーターで、内にあるリストの要素を取得する関数を呼び出すことで、ソートに使用するキー列を指定します。
2つ目の要素(チャンネル番号)でソートします。
要素の取得は、x[0]からなので、2つ目の要素はx[1]となる。
before = [[3, '2ch', 'NHK Eテレ東京'], [1, '8ch', 'フジテレビ'], [2, '4ch', '日テレ'] ]
after = sorted(before, key=lambda x: x[1])
print('before: ', before)
print('after : ', after)
before: [[3, '2ch', 'NHK Eテレ東京'], [1, '8ch', 'フジテレビ'], [2, '4ch', '日テレ']]
after : [[3, '2ch', 'NHK Eテレ東京'], [2, '4ch', '日テレ'], [1, '8ch', 'フジテレビ']]
2つ目の要素(チャンネル番号)でソートされています。
key関数に無名関数(ラムダ式)を使用しても、def文で関数を定義しても同じ結果になります。
def ch_No(x):
return x[1] # 2つめの要素を返す関数
before = [[3, '2ch', 'NHK Eテレ東京'], [1, '8ch', 'フジテレビ'], [2, '4ch', '日テレ'] ]
after = sorted(before, key=ch_No)
print('before: ', before)
print('after : ', after)
before: [[3, '2ch', 'NHK Eテレ東京'], [1, '8ch', 'フジテレビ'], [2, '4ch', '日テレ']]
after : [[3, '2ch', 'NHK Eテレ東京'], [2, '4ch', '日テレ'], [1, '8ch', 'フジテレビ']]
reverseパラメーターの使い方
sorted(reverse=False)は、デォルトで昇順(False)が設定されていて、省略ができます。
降順にするときは、reverseをTrueにします
before = [2, 4, 0, 5, 1]
after = sorted(before, reverse=True)
print('before: ', before)
print('after : ', after)
before: [2, 4, 0, 5, 1]
after : [5, 4, 2, 1, 0]
list.sortメソッドでソート
リストは、 リスト型のメソッドlist.sort()でソートできます。
list.sort(key=None, reverse=False )
list.sort()は、元のリストをソートします。
sort()は、リストのメソッドなので、変数の後にドット(.)を付けて使います。
before = [2, 4, 0, 5, 1]
after = before.sort()
print('before: ', before)
print('after : ', after)
before: [0, 1, 2, 4, 5]
after : None
before自身が昇順にソートされます。
sorted関数との混乱をさけるために、Noneが返されます。
パラメーター(key、reverse)の使い方は、sortedと同じです。
before = ['2', '02', '10', '3', '1']
after = before.sort(key=int, reverse=True)
print('before: ', before)
print('after : ', after)
before: ['10', '3', '2', '02', '1']
after : None
beforeを整数に変換して、降順にソートしています。
同じ値は、元のリスト順です。
複数keyでソート(operatorモジュール関数 )
operatorモジュールのitemgetter関数を使用すると、キー列を簡単に指定できます。
1つのkeyでソート
2つ目の要素でソートします。
from operator import itemgetter
before = [[3, '2ch', 'NHK Eテレ'], [1, '8ch', 'フジ'], [2, '4ch', '日テレ'] ]
after = sorted(before, key=itemgetter(1))
print('before: ', before)
print('after : ', after)
2つのkeyでソート
itemgetter関数は、複数の段階でのソートができます。
reverseは、複数のソートに共通します。
降順に、民放と公共放送でソート(0)してから、チャンネル番号順にソート(1)します。
before = [['公', '2ch', 'NHK Eテレ'], ['民', '8ch', 'フジ'], ['民', '4ch', '日テレ'] ]
after = sorted(before, key=itemgetter(0,1), reverse=True)
print('before: ', before)
print('after : ', after)
before: [['公', '2ch', 'NHK Eテレ'], ['民', '8ch', 'フジ'], ['民', '4ch', '日テレ']]
after : [['民', '8ch', 'フジ'], ['民', '4ch', '日テレ'], ['公', '2ch', 'NHK Eテレ']]
無名関数(ラムダ式)で2つのkeyを指定
無名関数(ラムダ式)でも、2つのkeyを指定してソートすることができます。
1つ目の要素でソートし、同じ要素のときに2つ目の要素でソートするときは、タプル()で囲みます。
before = [['公', '2ch', 'NHK Eテレ'], ['民', '8ch', 'フジ'], ['民', '4ch', '日テレ'] ]
after = sorted(before, key=lambda x: (x[0],x[1]), reverse=True)
print('before: ', before)
print('after : ', after)
before: [['公', '2ch', 'NHK Eテレ'], ['民', '8ch', 'フジ'], ['民', '4ch', '日テレ']]
after : [['民', '8ch', 'フジ'], ['民', '4ch', '日テレ'], ['公', '2ch', 'NHK Eテレ']]
まとめ
- リストのソートが、sorted()とlist.sort()の2つの方法でできました
- パラメーター(keyとreverse)の使い方がわかりました
- 複数keyでのソートができました