8

私はプログラミングが初めてで、現在Pythonでリーグテーブルを書いています。リーグを最初のポイントで並べ替えたいと思います。同じポイントを持つ 2 つのチームがある場合は得失点差で並べ替え、同じ得失点差がある場合は名前で並べ替えたいと思います。

最初の条件は非常に簡単で、次のように機能します。

table.sort(reverse=True, key=Team.getPoints)

次の2つの条件を挿入するにはどうすればよいですか?

4

3 に答える 3

14

関数がタプル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'))
于 2013-01-13T00:39:39.490 に答える
4

最初にリストを名前で並べ替え、次にスコア差で並べ替えます。Pythonsortは安定しています。つまり、等しい要素の順序を保持します。

于 2013-01-13T00:35:15.243 に答える
0

Python のソート アルゴリズムはTimsortであり、ACEfanatic02 が指摘するように安定しているため、順序が保持されます。このリンクには、それがどのように機能するかについての素晴らしい視覚的な説明があります。

于 2013-01-13T00:43:04.213 に答える