リストの要素が自作クラスのオブジェクトの場合に、そのオブジェクトのメンバ変数に対してソートをしたい。
やりたいこと
class Person(): def __init__(self, _id, height, name): self._id = _id self._height = height self._name = name def solve(): N = 5 p = [None] * N p[0] = Person(5, 160, "うえだ") p[1] = Person(2, 140, "いいだ") p[2] = Person(4, 140, "えのもと") p[3] = Person(1, 150, "あすのざか") p[4] = Person(3, 160, "おおの") # このとき、pをPersonのid順などでソートしたい def __name__ == "__main__": solve()
コード
# coding: utf-8 class Person(): def __init__(self, _id, height, name): self._id = _id self._height = height self._name = name self.latest_me = None # 最近振った目の数 @property def id(self): return self._id @property def height(self): return self._height @property def name(self): return self._name def toss_dice(self): """ 1~6の目のサイコロを振り、出た目の数を返す """ import random self.latest_me = random.randrange(1, 7) return self.latest_me def sort_height(p, N): print("--背の順でソートする--") # lambdaを使う場合 sorted_p = sorted(p, key=lambda person: person.height) # operator.attrgetterを使う場合(結果はlambdaを使った場合と同じ) from operator import attrgetter sorted_p = sorted(p, key=attrgetter("height")) for i in range(N): print("{}, {}, {}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name)) def sort_height_and_id(p, N): print("--背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ)--") from operator import attrgetter sorted_p = sorted(p, key=attrgetter("height", "id")) for i in range(N): print("{}, {}, {}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name)) def sort_dice(p, N): print("--サイコロを振り、出た目の数でソートする(実行するたびに変わる)--") # lambdaを使う場合 sorted_p = sorted(p, key=lambda person: person.toss_dice()) # operator.methodcallerを使う場合(結果はlambdaを使った場合と同じ) from operator import methodcaller sorted_p = sorted(p, key=methodcaller("toss_dice")) for i in range(N): print("{}, {}, {} : D{}".format(sorted_p[i].id, sorted_p[i].height, sorted_p[i].name, sorted_p[i].latest_me)) def solve(): N = 5 p = [None] * N p[0] = Person(5, 160, "うえだ") p[1] = Person(2, 140, "いいだ") p[2] = Person(4, 140, "えのもと") p[3] = Person(1, 150, "あすのざか") p[4] = Person(3, 160, "おおの") # 単純に表示する for i in range(N): print("{}, {}, {}".format(p[i].id, p[i].height, p[i].name)) # 背の順でソート sort_height(p, N) # 背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ) sort_height_and_id(p, N) # サイコロを振り、出た目の数でソートする(実行するたびに変わる) sort_dice(p, N) if __name__ == "__main__": solve()
↓結果
5, 160, うえだ 2, 140, いいだ 4, 140, えのもと 1, 150, あすのざか 3, 160, おおの --背の順でソートする-- 2, 140, いいだ 4, 140, えのもと 1, 150, あすのざか 5, 160, うえだ 3, 160, おおの --背の順でソートし、かつ、idが若い順にソートする(身長が同じ人はidが若い順に並ぶ)-- 2, 140, いいだ 4, 140, えのもと 1, 150, あすのざか 3, 160, おおの 5, 160, うえだ --サイコロを振り、出た目の数でソートする(実行するたびに変わる)-- 2, 140, いいだ : D1 3, 160, おおの : D1 5, 160, うえだ : D3 4, 140, えのもと : D3 1, 150, あすのざか : D4
おまけ
参考URL: