listのソートはよくありますが、ここではdict in listやinstance in listをsortする方法を書き留めます。
sortは全て昇順とします。
sortで使用するのは組み込み関数のsorted
です。
動作確認済みのPythonバージョン
- 3.7
- 3.8
標準ライブラリdataclassesを使用しなければ3.6とかでも動くはずです
dict in list
dict in listの場合はsorted関数のkey引数を指定してあげる必要があります。
keyを指定する時にlambda使って無名関数でlambda x: x['a']
でもいいですが、公式によると標準ライブラリoperatorのitemgetterを使用した方が高速らしいです(検証していないのでなんとも言えませんが)。
Python は高速で扱いやすいアクセサ関数を提供しています。 operator モジュールには itemgetter(), attrgetter() そして methodcaller() 関数があります。
from operator import itemgetter
person_list = [{'name': 'a', 'age': 4}, {'name': 'b', 'age': 3}, {'name': 'c', 'age': 10}, {'name': 'd', 'age': 2}, {'name': 'e', 'age': 1}]
sorted(person_list, key=itemgetter('age'))
[{'name': 'e', 'age': 1},
{'name': 'd', 'age': 2},
{'name': 'b', 'age': 3},
{'name': 'a', 'age': 4},
{'name': 'c', 'age': 10}]
instance in list
dict in listと同様にsorted関数のkey引数にソートしたいパラメータを指定してあげましょう。instanceの場合はattrgetterを使うといいですよ。
一旦sourcesでdict in list作成して、list(map(...))でインスタンス作成しているのに深い意味はありません。dict in listで使用したperson_listを流用して楽をしたかっただけです。
from dataclasses import dataclass
from operator import attrgetter
@dataclass
class Person:
name: str
age: int
sources = [{'name': 'a', 'age': 4}, {'name': 'b', 'age': 3}, {'name': 'c', 'age': 10}, {'name': 'd', 'age': 2}, {'name': 'e', 'age': 1}]
person_list = list(map(lambda x: Person(**x), sources))
sorted(person_list, key=attrgetter('age'))
[Person(name='e', age=1),
Person(name='d', age=2),
Person(name='b', age=3),
Person(name='a', age=4),
Person(name='c', age=10)]
降順でソートしたければ、sorted関数のreverse引数をTrueにすればOK