色々と。
単一項目でのソートはまー良いんだけど、
複数項目で、昇順/降順を個別指定してのソートは
サンプルとかあまり見なかったので↓の感じにした。
simple_list = [5,10,1,4,8,0] tuple_list = [(3,'b'),(10,'x'),(5,'z')] class TestItem: def __init__(self, **kwargs): self.id = kwargs["id"] self.name = kwargs["name"] self.val = kwargs["val"] def __repr__(self): return repr((self.id, self.name, self.val)) obj_list = [] obj_list.append(TestItem(id=10,name="y",val=1024)) obj_list.append(TestItem(id=1,name="z",val=256)) obj_list.append(TestItem(id=5,name="x",val=128)) obj_list.append(TestItem(id=101,name="y",val=512)) obj_list.append(TestItem(id=102,name="y",val=64)) dict_list = [] dict_list.append({"id":10, "name":"y", "val":1024}) dict_list.append({"id":1, "name":"z", "val":256}) dict_list.append({"id":5, "name":"x", "val":128}) dict_list.append({"id":101, "name":"y", "val":512}) dict_list.append({"id":102, "name":"y", "val":64}) from operator import attrgetter if __name__ == "__main__": # 普通にソート print(sorted(simple_list)) # → [0, 1, 4, 5, 8, 10] # 降順にソート print(sorted(simple_list, reverse=True)) # → [10, 8, 5, 4, 1, 0] # タプルの配列のソート(タプルの最初の項目でソート) print(sorted(tuple_list)) # → [(3, 'b'), (5, 'z'), (10, 'x')] # タプルの配列の降順でソート(タプルの指定の項目でソート) print(sorted(tuple_list, key=lambda x: x[1], reverse=True)) # → [(5, 'z'), (10, 'x'), (3, 'b')] # オブジェクトの配列のソート print(sorted(obj_list, key=lambda x: x.name)) # → [(5, 'x', 128), (10, 'y', 1024), (101, 'y', 512), (102, 'y', 64), (1, 'z', 256)] # オブジェクトの配列のソート(attrgetter使用) print(sorted(obj_list, key=attrgetter("name"))) # → [(5, 'x', 128), (10, 'y', 1024), (101, 'y', 512), (102, 'y', 64), (1, 'z', 256)] # 辞書の配列のソート print(sorted(dict_list, key=lambda x: x["name"])) # → [{'id': 5, 'name': 'x', 'val': 128}, {'id': 10, 'name': 'y', 'val': 1024}, {'id': 101, 'name': 'y', 'val': 512}, {'id': 102, 'name': 'y', 'val': 64}, {'id': 1, 'name': 'z', 'val': 256}] # ここから複合ソート # 複合ソート用関数 def multisort(xs, specs, fkey): for key, reverse in reversed(specs): xs.sort(key=fkey(key), reverse=reverse) return xs # key関数を作る高階関数(オブジェクト用) def fobj(key): return attrgetter(key) # key関数を作る高階関数(dict用) def fdict(key): return lambda x: x[key] # オブジェクトの配列の複合ソート print(multisort(obj_list, [('name', False), ('val', False)], fobj)) # → [(5, 'x', 128), (102, 'y', 64), (101, 'y', 512), (10, 'y', 1024), (1, 'z', 256)] # 辞書の配列の複合ソート print(multisort(dict_list, [('name', False), ('val', False)], fdict)) # → [{'id': 5, 'name': 'x', 'val': 128}, {'id': 102, 'name': 'y', 'val': 64}, {'id': 101, 'name': 'y', 'val': 512}, {'id': 10, 'name': 'y', 'val': 1024}, {'id': 1, 'name': 'z', 'val': 256}]
で、Pythonのソートは安定(同一値の場合に元の並び順のままになる)なのを
保証してるみたいなので、上のロジックで複数キーのソートが出来るとさ。。。