111

私は自分の古いコードをリファクタリングしていて、これに出くわしました:

alist.sort(cmp_items)

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

コードは機能します (そして私は約 3 年前に書きました!) しかし、Python のドキュメントのどこにもこのことが文書化されているのを見つけることができず、誰もがsorted()カスタムの並べ替えを実装するために使用しています。誰かがなぜこれが機能するのか説明できますか?

4

6 に答える 6

122

補足として、同じソートを実装するためのより良い代替手段を次に示します。

alist.sort(key=lambda x: x.foo)

または、次のようにします。

import operator
alist.sort(key=operator.attrgetter('foo'))

Sorting How To を確認してください。非常に便利です。

于 2012-08-07T16:49:06.373 に答える
26

この例のように。このリストを並べ替えます。

[('c', 2), ('b', 2), ('a', 3)]

出力:

[('a', 3), ('b', 2), ('c', 2)]

タプルを 2 番目の項目で並べ替え、次に最初の項目で並べ替える必要があります。

def letter_cmp(a, b):
    if a[1] > b[1]:
        return -1
    elif a[1] == b[1]:
        if a[0] > b[0]:
            return 1
        else:
            return -1
    else:
        return 1

次に、キー関数に変換します。

from functools import cmp_to_key
letter_cmp_key = cmp_to_key(letter_cmp))

これで、カスタムの並べ替え順序を使用できます。

[('c', 2), ('b', 2), ('a', 3)].sort(key=letter_cmp_key)
于 2016-03-18T03:26:22.477 に答える
14

これは Python 3 では機能しません。

ただし、 functools cmp_to_key を使用して、古いスタイルの比較関数を機能させることができます。

from functools import cmp_to_key

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

cmp_items_py3 = cmp_to_key(cmp_items)

alist.sort(cmp_items_py3)
于 2018-08-06T12:41:35.323 に答える