私はプログラミングが初めてで、現在Pythonでリーグテーブルを書いています。リーグを最初のポイントで並べ替えたいと思います。同じポイントを持つ 2 つのチームがある場合は得失点差で並べ替え、同じ得失点差がある場合は名前で並べ替えたいと思います。
最初の条件は非常に簡単で、次のように機能します。
table.sort(reverse=True, key=Team.getPoints)
次の2つの条件を挿入するにはどうすればよいですか?
関数がタプルkey
を返すようにします。アイテムは優先度の高い順に並べられています。
table.sort(reverse=True, key=lambda team: (Team.getPoints(team),
Team.getGoalDifference(team),
Team.getName(team))
別の方法として、アルゴリズム 101 のファクトイドを覚えておいて、ファクトイドが安定した並べ替えであることを利用することもできます。.sort()
したがって、リスト内のアイテムが等しい場合、アイテムの相対的な順序は変更されません。つまり、優先度の高い順に 3 回並べ替えることができます。
table.sort(reverse=True, key=Team.getName)
table.sort(reverse=True, key=Team.getGoalDifference)
table.sort(reverse=True, key=Team.getPoints)
これは遅くなりますが、各ステップを実行するかどうかを簡単に指定できますreverse
。これは、 を使用して複数の並べ替えパスを使用せずに実行できますcmp_to_key()
が、コンパレーター関数は次のように自明ではありません。
def team_cmp(t1, t2):
for key_func, reverse in [(Team.getName, True),
(Team.getGoalDifference, True),
(Team.getPoints, True)]:
result = cmp(key_func(t1), key_func(t2))
if reverse: result = -result;
if result: return result
return 0
table.sort(functools.cmp_to_key(team_cmp))
(免責事項: 上記はメモリから書かれており、テストされていません。) 強調されているのは「複数のパスがない」ことであり、必ずしも「速い」ことを意味するわけではありません。cmp_to_key()
どちらも Python で実装されている ( C コアの一部であるlist.sort()
および とは対照的に)コンパレーター関数 および からのオーバーヘッドは、かなりのものになる可能性があります。operator.itemgetter()
余談ですが、key
パラメーターに渡すダミー関数を作成する必要はありません。次を使用して、属性に直接アクセスできます。
table.sort(key=lambda t: t.points)
またはattrgetter
演算子ラッパー:
table.sort(key=attrgetter('points'))
最初にリストを名前で並べ替え、次にスコア差で並べ替えます。Pythonsort
は安定しています。つまり、等しい要素の順序を保持します。