60

重複の可能性:
降順値の Python ソートキー関数の書き方

Python 3 では、複数のキーを使用してオブジェクトのリストを辞書順で並べ替えるのは非常に簡単です。例えば:

items.sort(key = lambda obj: obj.firstname, obj.lastname)

引数を使用すると、reverse昇順または降順のどちらを使用するかを指定できます。しかし、複数のキーでソートしたいが、最初のキーは降順、2番目のキーは昇順でソートしたい場合はどうすればよいでしょうか?

たとえば、 と の 2 つの属性を持つオブジェクトがあるとします。ここで、 は でありpoints、はです。これらのオブジェクトのリストを降順で並べ替えます(ポイントの数が最も多いオブジェクトが最初になるように) が、同じ数のオブジェクトについては、これらをアルファベット (昇順) で並べ替えたいと考えています。namepointsintnamestrpointspointsname

これはどのように達成できますか?

4

3 に答える 3

38

これを処理する組み込みの方法はありません。一般的なケースでは、2 回ソートする必要があります。最初はセカンダリ ソートで、次にプライマリ ソートでソートします。@Mark Ransom がコメントで述べたように、多くの場合、変数は数値であるため、負の値を使用して順序を反転できます。

ソートしようとしている変数の型とその操作方法がわかっている場合は、増加するキーに対して減少する値を返すキー関数を作成することもできます。文字列の例については、このスレッドを参照してください。(基本的には文字のASCII数値のマイナスを取ります。)

Python 2 では、キーの代わりに関数を使用することもできましたcmpが、これによりソートが遅くなる可能性があります。遅くなりすぎるかどうかは、リストがどれだけ大きく、ソートされていないかによって異なります。Python 3 ではcmp引数はなくなりましたが、@Mark Ransom が指摘しているように、cmp_to_key.

于 2012-07-13T18:52:39.467 に答える
16
items.sort(key = lambda obj: (obj.firstname, [(-ord(c) for c in obj.lastname)]))
于 2012-07-13T19:47:20.807 に答える
8

functools.cmp_to_key比較関数をソート関数と互換性のあるキーに変換する必要があります。これは、Python 2 で比較関数を使用する並べ替えのために提供されていたもので、Python 3 に変換する必要があったため、それらが許可されなくなりました。

編集:Python wiki の見出し「Sort Stability and Complex Sorts 」の下に、最も重要でないキーから最も重要なキーへの複数のパスで並べ替えを行う提案もあります。これが機能するのは、Python の並べ替えが安定していることが保証されているためです。そのため、同等のキーが検出されたときに以前の順序が維持されます。

于 2012-07-13T18:53:59.440 に答える