このページはlistクラスのsortメソッドの解説です。
listクラスのオブジェクト以外のソートや非破壊的なソートをしたい場合は
組み込み関数のsortedの使用方法
を参照してください。
sort(リスト、配列)
このページでは豊富な例を用いてPythonの listクラス のsortメソッドの使い方を学ぶことができます。
sortは呼び出し元の listクラス のオブジェクトをソート(並び替え)します。デフォルトでは昇順です。
引数として2つのキーワード引数を取ることが可能です。
キーワード引数key
は比較対象のキーを設定しデフォルトの挙動を変更することができます。
キーワード引数reverse
はTrue
を設定することで降順ソートを実現することが可能です。
また、listクラスのsortは呼び出し元のlistオブジェクトを直接並び替える破壊的なメソッドです。
非破壊的な並び替え(呼び出し元のオブジェクト自体を並び替えない)をしたい場合は
組み込み関数のsorted
の使用を検討してください。
TL;DR
基本
# 配列の要素を昇順に並び替える
list1 = ['C', 'B', 'A', 'D']
list1.sort()
print(list1)
==> ['A', 'B', 'C', 'D']
# sort自体の返り値はNone
print(list1.sort())
==> None
# 昇順に並び替える
list2 = [2, 3, 1, 5, 4]
list2.sort()
print(list2)
==> [1, 2, 3, 4, 5]
list3 = ['2', '3', '1']
list3.sort()
print(list3)
==> ['1', '2', '3']
# 大文字・小文字が区別される
list4 = ['apple', 'Apple', 'banana', 'Banana']
list4.sort()
print(list4)
==> ['Apple', 'Banana', 'apple', 'banana']
# dictなどの一部のオブジェクトはそのままだとsortで並び替えることができずエラー
list5 = [{'id': 1, 'name': 'Olivia'}, {'id': 2, 'name': 'Joshua'}]
list5.sort()
print(list5)
==> TypeError: '<' not supported between instances of 'dict' and 'dict'
# 並び替えられないものが混在している場合はエラー
list6 = [5, 4, 3, 2, 1, 'a']
list6.sort()
print(list6)
==> TypeError: '<' not supported between instances of 'str' and 'int'
独自のソート方法を適用する
# 通常は大文字・小文字を区別する
list0 = ['Python', 'python', 'JavaScript', 'javascript']
list0.sort()
print(list0)
==> ['JavaScript', 'Python', 'javascript', 'python']
# 大文字化された文字列を返す関数
def to_upper_cases(element: str):
return element.upper()
# 大文字・小文字を区別しないソートを実現する関数をキーワード引数keyに指定
list1 = ['Python', 'python', 'JavaScript', 'javascript']
# ソートアルゴリズムを実行する前にlistの各要素がto_upper_casesの第1引数に渡され
# 大文字化された後に、ソート処理が実行される
list1.sort(key=to_upper_cases)
print(list1)
==> ['JavaScript', 'javascript', 'Python', 'python']
# ラムダ式(lambda)を指定することもできます
list2 = ['Python', 'python', 'JavaScript', 'javascript']
list2.sort(key=lambda element: element.upper())
print(list2)
==> ['JavaScript', 'javascript', 'Python', 'python']
# str.upperとすることでも実現可能です
list3 = ['Python', 'python', 'JavaScript', 'javascript']
list3.sort(key=str.upper)
print(list3)
==> ['JavaScript', 'javascript', 'Python', 'python']
# 3との差が小さい順にソートする
list4 = [1, 2, 3, 4, 5]
# 3との差の絶対値をラムダ式で求める
list4.sort(key=lambda e: abs(3 - e))
print(list4)
==> [3, 2, 4, 1, 5]
# dict型のオブジェクトもキーワード引数keyを使用して並び替え可能になる
list5 = [{'name': 'Lisa', 'age': 26}, {'name': 'John', 'age': 22}]
list5.sort(key=lambda e: e['age'])
print(list5)
==> [{'name': 'John', 'age': 22}, {'name': 'Lisa', 'age': 26}]
# 独自クラスに対しても並べ替えできます
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr((self.name, self.age))
list6 = [Person('Lisa', 26), Person('John', 22)]
print(list6)
==> [('Lisa', 26), ('John', 22)]
# age順にソート
list6.sort(key=lambda e: e.age)
print(list6)
==> [('John', 22), ('Lisa', 26)]
関連情報:def(関数定義)の使用方法
関連情報:abs(組み込み関数)の使用方法
関連情報:lambda(ラムダ式)の使用方法
関連情報:class(クラス定義)の使用方法
operatorモジュール関数の使用
from operator import itemgetter, attrgetter
list1 = [{'name': 'Lisa', 'age': 26}, {'name': 'John', 'age': 22}]
# operatorモジュール関数を使用すると以下の表現と同様の挙動を実現できる
# list1.sort(key=lambda e: e['age'])
list1.sort(key=itemgetter('age'))
print(list1)
==> [{'name': 'John', 'age': 22}, {'name': 'Lisa', 'age': 26}]
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr((self.name, self.age))
list2 = [Person('Lisa', 26), Person('John', 22)]
# operatorモジュール関数を使用すると以下の表現と同様の挙動を実現できる
# list1.sort(key=lambda e: e.age)
list2.sort(key=attrgetter('age'))
print(list2)
==> [('John', 22), ('Lisa', 26)]
list3 = [(1, 10, 3), (3, 0, 5), (1, 0, 0)]
# 各tuple型オブジェクトのインデックス1の値を基準としてソートする
list3.sort(key=itemgetter(1))
print(list3)
==> [(3, 0, 5), (1, 0, 0), (1, 10, 3)]
# list3と同じ構造のlistをインデックス1の値とインデックス2の値を基準にソートする
# ソート方法の優先度は引数の順番と同様です
list4 = [(1, 10, 3), (3, 0, 5), (1, 0, 0)]
list4.sort(key=itemgetter(1, 2))
print(list4)
==> [(1, 0, 0), (3, 0, 5), (1, 10, 3)]
昇順・降順の指定
# そのままソートすると昇順
list1 = [2, 3, 5, 4, 1]
list1.sort()
print(list1)
==> [1, 2, 3, 4, 5]
# キーワード引数reverseを使用して降順でソート
list2 = [2, 3, 5, 4, 1]
list2.sort(reverse=True)
print(list2)
==> [5, 4, 3, 2, 1]
# keyとreverseの併用
list3 = [{'id': 3, 'name': 'John'}, {'id': 1, 'name': 'Alisha'}, {'id': 2, 'name': 'Anaisha'}]
list3.sort(key=lambda e: e['id'], reverse=True)
print(list3)
==> [{'id': 3, 'name': 'John'}, {'id': 2, 'name': 'Anaisha'}, {'id': 1, 'name': 'Alisha'}]
類似関数sorted
list1 = ['C', 'B', 'A', 'D']
sorted_list1 = sorted(list1)
# list1自体に変更はなし
print(list1)
==> ['C', 'B', 'A', 'D']
print(sorted_list1)
==> ['A', 'B', 'C', 'D']
list2 = ['Python', 'python', 'JavaScript', 'javascript']
# 大文字・小文字を無視した並び替え
sorted_list2 = sorted(list2, key=str.lower)
print(sorted_list2)
==> ['JavaScript', 'javascript', 'Python', 'python']
tuple1 = (2, 4, 3, 1, 5)
sorted_list3 = sorted(tuple1, reverse=True)
# 返り値はtupleオブジェクトではなくlistオブジェクトです
print(sorted_list3)
==> [5, 4, 3, 2, 1]
関連情報:sorted関数の使用方法
解説
基本
sortは引数を指定しないで呼び出すと、呼び出し元のlistオブジェクトを昇順でソートします。
その際、呼び出し元のオブジェクトを直接変更するので注意してください。
また、デフォルトでは大文字・小文字が区別されたソートが行われ、要素同士がソートできないとエラーが発生します。
# 配列の要素を昇順に並び替える
list1 = [5, 4, 3, 2, 1]
list1.sort()
print(list1)
==> [1, 2, 3, 4, 5]
# sort自体の返り値はNone
print(list1.sort())
==> None
# 大文字・小文字が区別される
list2 = ['Python', 'python', 'JavaScript', 'javascript']
list2.sort()
print(list2)
==> ['JavaScript', 'Python', 'javascript', 'python']
# 並び替えられない場合はエラー
list3 = ['Python', 100, {1: 'first'}, 'Go']
list3.sort()
print(list3)
==> TypeError: '<' not supported between instances of 'int' and 'str'
独自のソート方法を適用する
sortメソッドはキーワード引数key
を指定することでデフォルトのソートから挙動を変更することができます。
key
には引数を1つ持つ関数を指定し、呼び出し元のlistの各要素についてこの関数がキー値を計算してからソートが行われます。
ラムダ式(lambda)やoperatorモジュール関数(operator module functions、次項で説明)も指定することが可能で、
より簡潔にキー値の計算・指定方法を記述できます。
key
に関数をわたす際には丸括弧()
をつけないように気をつけてください。
# 絶対値の昇順にソートする
list1 = [-2, -1, 0, 1, 2]
list1.sort(key=abs)
print(list1)
==> [0, -1, 1, -2, 2]
# 独自関数を作り文字列のインデックス1の文字でソートする
def index1_string(e: str):
return e[1]
list2 = ['Python', 'python', 'JavaScript', 'javascript']
list2.sort(key=index1_string)
print(list2)
==> ['JavaScript', 'javascript', 'Python', 'python']
# ラムダ式を指定してLanguageオブジェクトをrank順にソートする
class Language:
def __init__(self, name, rank):
self.name = name
self.rank = rank
def __repr__(self):
return repr((self.name, self.rank))
list3 = [Language('Smalltalk', 2), Language('Lisp', 3), Language('COBOL', 1)]
print(list3)
==> [('Smalltalk', 2), ('Lisp', 3), ('COBOL', 1)]
list3.sort(key=lambda language: language.rank)
print(list3)
==> [('COBOL', 1), ('Smalltalk', 2), ('Lisp', 3)]
関連情報:def(関数定義)の使用方法
関連情報:abs(組み込み関数)の使用方法
関連情報:lambda(ラムダ式)の使用方法
関連情報:class(クラス定義)の使用方法
operatorモジュール関数の使用
キーワード引数key
にはoperatorモジュール関数も指定可能です。
オブジェクトのプロパティ値の指定や、複数のソートキーの指定を簡潔に記述することができます。
使用方法はTL;DRのoperatorモジュール関数の使用
のコードも合わせて参照してください。
from operator import attrgetter
class Language:
def __init__(self, name, rank):
self.name = name
self.rank = rank
def __repr__(self):
return repr((self.name, self.rank))
list1 = [Language('Smalltalk', 2), Language('Lisp', 3), Language('COBOL', 1)]
# attrgetterを使用すると以下の表現と同様の挙動を実現できる
# list1.sort(key=lambda language: language.rank)
list1.sort(key=attrgetter('rank'))
print(list1)
==> [('COBOL', 1), ('Smalltalk', 2), ('Lisp', 3)]
昇順・降順の指定
キーワード引数reverse
を指定することでデフォルトのソート順序(昇順)を変更することができます。
指定する値はbool
型で、True
を設定することで降順のソートを実現できるようになります。
# 降順でソート
list1 = ['B', 'C', 'A', 'D']
list1.sort(reverse=True)
print(list1)
==> ['D', 'C', 'B', 'A']
# keyとreverseの併用
list2 = [(2, 'Aahva'), (1, 'Dasya'), (3, 'Aya')]
list2.sort(key=lambda e: e[1], reverse=True)
print(list2)
==> [(1, 'Dasya'), (3, 'Aya'), (2, 'Aahva')]
類似関数sorted
listクラスのsortは呼び出し元のオブジェクトを直接変更する破壊的なメソッドです。
破壊的な変更をしたくない場合や、他のオブジェクトをソートしたい場合には
組み込み関数のsorted
の使用を考えるとよいかもしれません。
使用方法は似ており、このページでは簡潔にsortedの使用例を挙げるので、
より詳しく知りたい場合は上記のリンクを参照してください。
# 絶対値の昇順にソートする
list1 = [-2, -1, 0, 1, 2]
sorted_list1 = sorted(list1, key=abs)
# list1自体に変更はなし
print(list1)
==> [-2, -1, 0, 1, 2]
print(sorted_list1)
==> [0, -1, 1, -2, 2]
# 反復可能(iterable)なオブジェクトを引数に取ることができる
string1 = 'ABCDEFG'
sorted_list2 = sorted(string1, reverse=True)
print(string1)
==> ABCDEFG
print(sorted_list2)
==> ['G', 'F', 'E', 'D', 'C', 'B', 'A']