このページは組み込み関数のsortedの解説です。
listクラスのsortメソッドの解説は
sortメソッド(listクラス)の使用方法
を参照してください。
sorted
このページでは豊富な例を用いてPythonのsortedの使い方を学ぶことができます。
組み込み関数(built-in)のsortedは反復可能(iterable)なオブジェクトの要素を 昇順にソートしたlistオブジェクトを戻り値(返り値)として返します。
引数として1つの反復可能オブジェクト、2つのキーワード引数を取ることができます。
キーワード引数key
は比較対象のキーを設定しデフォルトのソート挙動を変更することができます。
キーワード引数reverse
はソート順序を変更することが可能です。
また、組み込み関数sortedは第1引数に与える反復可能オブジェクト自体を変更しない非破壊的な関数です。
listオブジェクトを破壊的に並び替えたい場合(呼び出し元のlist(リスト)自体を直接並び替える)は
sortメソッド(listクラス)
の使用を検討してください。
TL;DR
基本
# 第1引数に反復可能(iterable)オブジェクトを取ります
list1 = [4, 3, 1, 2]
sorted_list1 = sorted(list1)
# 元のオブジェクトには変化なし
print(list1)
==> [4, 3, 1, 2]
# 戻り値はlist型で昇順に並び替え
print(sorted_list1)
==> [1, 2, 3, 4]
# 文字列も反復可能オブジェクトです
string1 = 'FDACBE'
sorted_list2 = sorted(string1)
print(sorted_list2)
==> ['A', 'B', 'C', 'D', 'E', 'F']
# デフォルトでは大文字・小文字を区別します
tuple1 = ('Python', 'Java', 'java', 'python')
sorted_list3 = sorted(tuple1)
print(sorted_list3)
==> ['Java', 'Python', 'java', 'python']
# 昇順に並んだキーのlistを得ることができる
dict1 = {'id': 3, 'name': 'Jonas', 'age': 20}
sorted_list4 = sorted(dict1)
print(sorted_list4)
==> ['age', 'id', 'name']
# bool型の場合
tuple2 = (True, False, True, False, True)
sorted_list5 = sorted(tuple2)
print(sorted_list5)
==> [False, False, True, True, True]
# dateオブジェクトのソート
from datetime import date
list2 = [date(2020, 11, 30), date(2020, 10, 1), date(2019, 1, 3)]
# ソート前
for d in list2:
print(d, end=' ')
==> 2020-11-30 2020-10-01 2019-01-03
# ソート後
sorted_list6 = sorted(list2)
for d in sorted_list6:
print(d, end=' ')
==> 2019-01-03 2020-10-01 2020-11-30
# 並び替えられないオブジェクトが混在している場合はエラー
list3 = ['python', 'java', 5, 100]
sorted_list7 = sorted(list3)
==> TypeError: '<' not supported between instances of 'int' and 'str'
関連情報:forの使用方法
独自のソート方法を適用する
# 通常は大文字・小文字を区別する
list1 = ['Kiwi', 'Banana', 'Apple', 'apple', 'kiwi', 'banana']
sorted_list1 = sorted(list1)
print(sorted_list1)
==> ['Apple', 'Banana', 'Kiwi', 'apple', 'banana', 'kiwi']
# 要素を小文字にしてからソートをかけ、実質大文字・小文字を区別しない(戻り値の値は元のまま)
sorted_list2 = sorted(list1, key=str.lower)
print(sorted_list2)
==> ['Apple', 'apple', 'Banana', 'banana', 'Kiwi', 'kiwi']
# 通常ソート
list2 = ['Ad', 'Bc', 'Da', 'Cb']
print(sorted(list2))
==> ['Ad', 'Bc', 'Cb', 'Da']
# list2の各要素のインデックスが1の文字についてソートする
def index1_string(e: str):
return e[1]
print(sorted(list2, key=index1_string))
==> ['Da', 'Cb', 'Bc', 'Ad']
# 上記のソートをラムダ式(lambda)を用いて表現する
print(sorted(list2, key=lambda e: e[1]))
==> ['Da', 'Cb', 'Bc', 'Ad']
tuple1 = ({'name': 'Lisa', 'age': 26}, {'name': 'John', 'age': 22})
# dict型の要素は普通にはソートできない
print(sorted(tuple1))
==> TypeError: '<' not supported between instances of 'dict' and 'dict'
# dict型のオブジェクトもキーワード引数keyを使用して並び替え可能になる
# ラムダ式で比較キーとしてageを指定する
sorted_list3 = sorted(tuple1, key=lambda e: e['age'])
print(sorted_list3)
==> [{'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))
list3 = [Person('Anushka', 42), Person('Aahva', 26), Person('Atiksh', 50), Person('Khushi', 19)]
print(list3)
==> [('Anushka', 42), ('Aahva', 26), ('Atiksh', 50), ('Khushi', 19)]
# ここで定義したPersonクラスでは普通にはソートできない
print(sorted(list3))
==> TypeError: '<' not supported between instances of 'Person' and 'Person'
# keyで比較キーをageプロパティにするラムダ式を指定
sorted_list4 = sorted(list3, key=lambda person: person.age)
print(sorted_list4)
==> [('Khushi', 19), ('Aahva', 26), ('Anushka', 42), ('Atiksh', 50)]
関連情報:lambda(ラムダ式)の使用方法
関連情報:class(クラス定義)の使用方法
operatorモジュール関数の使用
from operator import itemgetter, attrgetter
list1 = [{'name': 'Lisa', 'age': 26}, {'name': 'John', 'age': 22}]
# operatorモジュール関数を使用すると以下の表現と同様の挙動を実現できる
# sorted(list1 , key=lambda e: e['age'])
sorted_list1 = sorted(list1, key=itemgetter('age'))
print(sorted_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))
tuple1 = (Person('Lisa', 26), Person('John', 22))
# operatorモジュール関数を使用すると以下の表現と同様の挙動を実現できる
# sorted(tuple1, key=lambda e: e.age)
sorted_list2 = sorted(tuple1, key=attrgetter('age'))
print(sorted_list2)
==> [('John', 22), ('Lisa', 26)]
list2 = [(1, 'C', 3), (2, 'A', 3), (3, 'B', 0)]
# 各tuple型オブジェクトのインデックス2の値を基準としてソートする
sorted_list3 = sorted(list2, key=itemgetter(2))
print(sorted_list3)
==> [(3, 'B', 0), (1, 'C', 3), (2, 'A', 3)]
# 各tuple型オブジェクトのインデックス2の値とインデックス1の値を基準にソートする
# 比較キーの優先度は引数の順番と同様です
sorted_list4 = sorted(list2, key=itemgetter(2, 1))
print(sorted_list4)
==> [(3, 'B', 0), (2, 'A', 3), (1, 'C', 3)]
昇順・降順の指定
string1 = 'fedcba'
# 通常ソート(昇順)
print(sorted(string1))
==> ['a', 'b', 'c', 'd', 'e', 'f']
# キーワード引数reverseにTrueをわたすと降順ソートを実現できる
print(sorted(string1, reverse=True))
==> ['f', 'e', 'd', 'c', 'b', 'a']
# keyとreverseの併用
list2 = [{'id': 3, 'name': 'John'}, {'id': 1, 'name': 'Alisha'}, {'id': 2, 'name': 'Anaisha'}]
# 'id'というキーのバリューの降順にソートする
sorted_list1 = sorted(list2, key=lambda e: e['id'], reverse=True)
print(sorted_list1)
==> [{'id': 3, 'name': 'John'}, {'id': 2, 'name': 'Anaisha'}, {'id': 1, 'name': 'Alisha'}]
類似メソッドsort
list1 = ['C', 'B', 'A', 'D']
list1.sort()
# 呼び出し元のオブジェクトを直接変更する
print(list1)
==> ['A', 'B', 'C', 'D']
# sortメソッド自体の戻り値はNone
print(list1.sort())
==> None
# キーワード引数keyを使用した大文字・小文字を無視した並び替え
list2 = ['Python', 'python', 'JavaScript', 'javascript']
list2.sort(key=str.lower)
print(list2)
==> ['JavaScript', 'javascript', 'Python', 'python']
# キーワード引数reverseの使用
list3 = [2, 4, 3, 1, 5]
list3.sort(reverse=True)
print(list3)
==> [5, 4, 3, 2, 1]
# sortメソッドはlistクラスのオブジェクトのみに使用できる
tuple1 = (0, 1, 2)
tuple1.sort()
==> AttributeError: 'tuple' object has no attribute 'sort'
解説
基本
組み込み関数のsortedは反復可能オブジェクトの要素をソートし、戻り値(返り値)としてソートされた要素をもつlistを返します。
引数で渡されたソート対象のオブジェクトに対しては変更を行わず、新たなlistを戻り値とする非破壊的な関数です。
また、デフォルトでは大文字・小文字が区別されたソートが行われ、要素同士がソートできないとエラーが発生します。
string1 = 'fedcba'
sorted_list1 = sorted(string1)
# 元のオブジェクトには変化なし
print(string1)
==> fedcba
# 戻り値はlist型で昇順に並び替え
print(sorted_list1)
==> ['a', 'b', 'c', 'd', 'e', 'f']
tuple1 = (53, 443, 80, 143)
sorted_list2 = sorted(tuple1)
print(sorted_list2)
==> [53, 80, 143, 443]
from datetime import date
list1 = [date(2020, 5, 1), date(1989, 6, 16), date(2019, 6, 24)]
for d in list1:
print(d, end=' ')
==> 2020-05-01 1989-06-16 2019-06-24
sorted_list3 = sorted(list1)
for d in sorted_list3:
print(d, end=' ')
==> 1989-06-16 2019-06-24 2020-05-01
関連情報:forの使用方法
独自のソート方法を適用する
sortedはキーワード引数key
を第2引数以降に指定することで、デフォルトのソートから挙動を変更することができます。
key
には引数が1つの関数を指定し、ソート対象の反復可能オブジェクトの各要素に対してこの関数がキー値を計算してからソートが行われます。
ラムダ式(lambda)やoperatorモジュール関数(operator module functions、次項で説明)も指定することが可能であり、
より簡潔にキー値の計算・指定方法を記述できます。
key
に関数をわたす際には丸括弧()
をつけないように気をつけてください。
tuple1 = (-2, -1, 0, 1, 2)
# 通常ソート
print(sorted(tuple1))
==> [-2, -1, 0, 1, 2]
# 絶対値の昇順にソート
sorted_list1 = sorted(tuple1, key=abs)
print(sorted_list1)
==> [0, -1, 1, -2, 2]
# 独自関数を作り文字列のインデックス1の文字でソートする
def index1_string(e: str):
return e[1]
list2 = ['Python', 'python', 'JavaScript', 'javascript']
# 通常ソート
print(sorted(list2))
==> ['JavaScript', 'Python', 'javascript', 'python']
# 各要素のインデックスが1の文字を比較キーにしてソートする
sorted_list2 = sorted(list2, key=index1_string)
print(sorted_list2)
==> ['JavaScript', 'javascript', 'Python', 'python']
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)]
# ここで定義したLanguageクラスでは普通にはソートできない
print(sorted(list3))
==> TypeError: '<' not supported between instances of 'Language' and 'Language'
# ラムダ式を指定してLanguageオブジェクトをrank順にソートする
sorted_list3 = sorted(list3, key=lambda language: language.rank)
print(sorted_list3)
==> [('COBOL', 1), ('Smalltalk', 2), ('Lisp', 3)]
関連情報:def(関数定義)の使用方法
関連情報:class(クラス定義)の使用方法
関連情報:lambda(ラムダ式)の使用方法
関連情報:abs(組み込み関数)の使用方法
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))
tuple1 = (Language('Smalltalk', 2), Language('Lisp', 3), Language('COBOL', 1))
# attrgetterを使用すると以下の表現と同様の挙動を実現できる
# list1.sort(key=lambda language: language.rank)
sorted_list1 = sorted(tuple1, key=attrgetter('rank'))
print(sorted_list1)
==> [('COBOL', 1), ('Smalltalk', 2), ('Lisp', 3)]
昇順・降順の指定
キーワード引数reverse
を指定することでデフォルトのソート順序(昇順)を変更することができます。
指定する値はbool
型で、True
を設定することで降順のソートを実現できるようになります。
# 降順でソート
tuple1 = ('B', 'C', 'A', 'D')
sorted_list1 = sorted(tuple1, reverse=True)
print(sorted_list1)
==> ['D', 'C', 'B', 'A']
# keyとreverseの併用
list1 = [(3, 'Aya'), (1, 'Dasya'), (2, 'Aahva')]
sorted_list2 = sorted(list1, key=lambda e: e[1], reverse=True)
print(sorted_list2)
==> [(1, 'Dasya'), (3, 'Aya'), (2, 'Aahva')]
類似メソッドsort
組み込み関数のsortedは呼び出し元のオブジェクトを変更しない非破壊的な関数です。
list型のオブジェクトを直接変更したい場合には sort(listクラス) の使用を検討してください。 使用方法は似ており、このページでは簡潔にlistクラスのsortメソッドの使用例を挙げるのでより詳しく知りたい場合は上記のリンクを参照してください。
# 絶対値の昇順にソートする
list1 = [-2, -1, 0, 1, 2]
list1.sort(key=abs)
# list1自体が直接変更される
print(list1)
==> [0, -1, 1, -2, 2]
# sort自体の戻り値はNone
print(list1.sort())
==> None
# sortメソッドはlistクラスのオブジェクトのみに使用できる
string1 = 'ABCDEFG'
string1.sort(reverse=True)
==> AttributeError: 'str' object has no attribute 'sort'
関連情報:abs(組み込み関数)の使用方法