【Python入門】リストのソート(昇順、降順、複数key)

list-sort list

リストの要素をソート(並び替え)する方法です。

リストは、数値や文字列を自由に登録できる便利な配列なので、 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の要素余り(剰余)
22
41
00
52
11

余りが小さい順にソートし、余りが同じときは元のリスト順になります。


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でのソートができました

関連情報

タイトルとURLをコピーしました