[解決!Python]リスト(配列)をソートしたり、逆順にしたりするには(sort/reverseメソッド、sorted/reversed関数):解決!Python
sortメソッドやsorted関数でリスト(配列)の要素をソートしたり、reverseメソッドやreversed関数で要素を逆順に並べたりする方法を紹介する。
# リストの要素をソートする(インプレース)
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
mylist.sort()
print(mylist) # [0, 1, 2, 5, 6, 7, 9, 15, 16, 18]
# リストの要素をソートした新しいリストを作成する
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
newlist = sorted(mylist)
print('mylist:', mylist) # mylist: [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
print('newlist:', newlist) # newlist: [0, 1, 2, 5, 6, 7, 9, 15, 16, 18]
# リストの要素をソートする(インプレース/逆順)
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
mylist.sort(reverse=True)
print(mylist) # [18, 16, 15, 9, 7, 6, 5, 2, 1, 0]
# ソートに使用するキーを決定する関数を指定
mylist = [-1.7, 0.1, 4.5, -1.5, -4.6]
mylist.sort(key=abs) # 絶対値順でソート
print(mylist) # [0.1, -1.5, -1.7, 4.5, -4.6]
# ラムダ式を使って、リストのリストをソートする
mylist = [[0, 1, 2], [1, 2, 0], [2, 0, 1]]
mylist.sort(key=lambda x: x[1]) # 1番目の要素をキーとしてリストをソート
print(mylist) # [[2, 0, 1], [0, 1, 2], [1, 2, 0]]
# keyキーワード引数とreverseキーワード引数を使用
mylist = [-1.7, 0.1, 4.5, -1.5, -4.6]
mylist.sort(key=abs, reverse=True) # 絶対値を基に降順でソート
print(mylist) # [-4.6, 4.5, -1.7, -1.5, 0.1]
# 要素を逆順に並べ替える(インプレース)
mylist = list(range(5)) # [0, 1, 2, 3, 4]
mylist.reverse()
print(mylist) # [4, 3, 2, 1, 0]
# 要素を逆順に並べ替えた新しいイテレータを作成する
mylist = list(range(5)) # [0, 1, 2, 3, 4]
iterator = reversed(mylist) # reversed関数の戻り値はイテレータ
print(iterator) # <list_reverseiterator object at ...>
newlist = list(iterator) # イテレータからリストを作成
print('mylist:', mylist) # mylist: [0, 1, 2, 3, 4]
print('newlist:', newlist) # newlist: [4, 3, 2, 1, 0]
sortメソッドとsorted関数
リスト(配列)の要素をソートするには、リストが持つsortメソッドかPythonに組み込みのsorted関数を使う。前者はリストをインプレースに変更する。つまり、元のリストの要素が直接変更される。後者は、リストの要素をソートした結果の新しいリストを作成する。
以下に例を示す。
# リストの要素をソートする(インプレース)
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
mylist.sort()
print(mylist) # [0, 1, 2, 5, 6, 7, 9, 15, 16, 18]
# リストの要素をソートした新しいリストを作成する
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
newlist = sorted(mylist)
print('mylist:', mylist) # mylist: [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
print('newlist:', newlist) # newlist: [0, 1, 2, 5, 6, 7, 9, 15, 16, 18]
1つ目の例ではリストmylistのsortメソッドを呼び出している。このため、リストの要素がインプレースで並べ替えられている。対して、2つ目の例ではsorted関数にリストmylistを渡しているので、元のリストでは要素は以前のままで、sortedメソッドの戻り値であるnewlistでは要素がソートされている。
sortメソッドやsorted関数を使ってソートを行う際には、内部的には<演算子を使ってそれぞれの要素の大小関係が比較されている。このため、リストに含まれている全ての要素同士をこの演算子で比較できる必要がある。例えば、整数と浮動小数点数の2種類の値だけがリストの要素であれば、問題なくソートできる。
mylist = [3.0, 0, 1.1, 2]
mylist.sort() # 整数と浮動小数点数の比較はサポートされている
print(mylist) # [0, 1.1, 2, 3.0]
これに対して、リストに文字列と整数値が含まれているというときには例外となる。
mylist = [3, 0, '1', 2]
mylist.sort() # TypeError:整数と文字列の比較はサポートされていない
このようなときには、何らかの形で要素の型を互換性のあるものに統一できるのであれば、以下で紹介するkeyキーワード引数に型変換するための関数を指定すれば、ソートすることは可能だ(そうした行為に意味があるかどうかは時と場合によるだろう)。
mylist = [3, 0, '1', 2]
mylist.sort(key=int) # 文字列を整数値に。「key=str」も同様
print(mylist) # [0, '1', 2, 3]
sortメソッドとsorted関数にはreverseとkeyという2つのキーワード引数がある。
reverseキーワード引数はソートを昇順/降順に行うかどうかを指定するものだ。これをTrueに指定すると、ソートの結果は通常とは逆の順序(降順)になる。
以下に例を示す。
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
mylist.sort(reverse=True)
print(mylist) # [18, 16, 15, 9, 7, 6, 5, 2, 1, 0]
mylist = [18, 0, 16, 6, 15, 7, 9, 1, 2, 5]
newlist = sorted(mylist, reverse=True)
print(newlist) # [18, 16, 15, 9, 7, 6, 5, 2, 1, 0]
先ほども出てきたもう1つのkeyキーワード引数は、要素を比較する際のキーとなる値を決定するのに使う関数を指定する。この関数は1つの引数を受け取り、何らかの値を返すものである必要がある。
以下に例を示す。
mylist = [-1.7, 0.1, 4.5, -1.5, -4.6]
mylist.sort(key=abs) # 絶対値順でソート
print(mylist) # [0.1, -1.5, -1.7, 4.5, -4.6]
mylist = [-1.7, 0.1, 4.5, -1.5, -4.6]
newlist = sorted(mylist, key=abs)
print(newlist) # [0.1, -1.5, -1.7, 4.5, -4.6]
この例では、正負の浮動小数点数値がリストの要素となっている。そして、keyキーワード引数にPythonに組み込みのabs関数を指定して、sortメソッドを呼び出している。そのためここでは、リストの各要素をabs関数に渡した結果、つまり各要素の絶対値を基に要素の並べ替えが行われる。
このように既存の関数(や自作の関数)を指定することもできるが、ラムダ式を使うことも可能だ。例として、リストを要素とするリストで、要素となっているリストをソートすることを考える。keyキーワード引数を指定しなければ、リストとリストが<演算子で比較されるが、簡単なラムダ式を書くだけで、要素となっているリストの何番目かの要素を基にソートを行える。
mylist = [['isshiki', 175, 68], ['kawasaki', 172, 80], ['endo', 180, 75]]
mylist.sort() # キー関数を指定せずにソート
print(mylist) # [['endo', 180, 75], ['isshiki', 175, 68], ['kawasaki', 172, 80]]
mylist.sort(key=lambda x: x[1]) # 1番目の要素をキーとしてリストをソート
print(mylist) # [['kawasaki', 172, 80], ['isshiki', 175, 68], ['endo', 180, 75]]
newlist = sorted(mylist, key=lambda x: x[2]) # 2番目の要素をキーとしてソート
print(newlist) # [['isshiki', 175, 68], ['endo', 180, 75], ['kawasaki', 172, 80]]
ここでは[名前, 身長, 体重]という要素で構成されるリストを要素とするリストがある。キー関数を指定せずにソートを行ったのが一番上の例だ。次の例では、keyキーワード引数に「lambda x: x[1]」を指定してソートをしているので、身長の低い順にリストがソートされている。最後の例ではkeyキーワード引数に「lambda x: x[2]」を指定しているので、体重が少ない順にソートが行われている。
Copyright© Digital Advantage Corp. All Rights Reserved.