次のようなカスタム関数があるとします
def greater(a, b):
if (a % b) % 2 == 0:
return 1
return 0
2つの数値を比較し、どちらが大きいかを判別する方法を定義します。この場合、関数が1 a> bを返すと、a <bになります。作り付けの<built-in function sorted> or
この定義に関して、並べ替えられた数値の配列を作成しますか?
Python 2.xを使用している場合、これはcmp
を使用して簡単に実現できますが、0ではなく-1を返すように関数を変更する必要があります。このようなもの:
def greater(a, b):
if (a % b) % 2 == 0:
return 1
return -1
x = [2,7,5,10,30,15]
print(sorted(x, cmp=greater))
ただし、Python 3.xを使用している場合は、cmp
が削除されたため、少し複雑になります。数値を保持するクラスを実装し、比較演算子を上書きする__lt__
(より小)および__gt__
(より大きい)。このようなもの:
class my_int(int):
def __lt__(a,b):
return (a % b) % 2 != 0
def __gt__(a,b):
return (a % b) % 2 == 0
x = [my_int(2),my_int(7),my_int(5),my_int(10),my_int(30),my_int(15)]
print (sorted(x))
番号。
一部のxとyの値についてはgreater(x, y) != not greater(y, x)
であるため、関数は数値をソートする方法について一貫した回答を提供しません。たとえば、_(3 % 4) % 2 == 1
_および_(4 % 3) % 2 == 1
_も使用できます。つまり、_3 > 4
_および_3 < 4
_は意味がありません。 @SystemDownが提案するようなcmpスタイルの関数に変換すると、一貫性のない結果が得られます。例えば:
_>>> sorted(range(3, 6), cmp=greater)
[5, 4, 3]
>>> sorted(range(1, 6), cmp=greater)
[1, 4, 3, 5, 2]
_
同じ比較関数を使用すると、5は4より小さい場合と4より大きい場合があります。
Cmp関数は自己矛盾がない場合でも、@ zstewartによって提案された_cmp_to_key
_関数を使用するなど、cmp関数は読み取りとデバッグが遅いため、何らかの方法や形式で使用しないことをお勧めします同等のキー機能。
キー関数を使用すると、関数はソートされるアイテムごとに1回だけ呼び出されるため、100万個のアイテムのリストがある場合、100万回呼び出されます。次に、ソートが進行し、キー関数の戻り値を平均してn*log(n)
回比較します。 100万個の要素のリストでは、1380万回です。
代わりにcmp関数を使用する場合、n*log(n)
の比較ごとに1回呼び出されます。繰り返しますが、リストに100万個の要素が含まれている場合は、1380万回です。 _cmp_to_key
_を使用すると、ヘルパークラスのインスタンスを100万個インスタンス化するという追加のオーバーヘッドが発生します。
同じことを実行するこれらの関数を使用して、100万のランダムな整数のリストでテストしました。
_def cmp_func(a, b):
if a > b:
return -1
Elif a < b:
return 1
else:
return 0
def key_func(x):
return -x
_
_key_func
_を使用した並べ替えには1.35秒かかりましたが、_cmp_func
_を使用すると2.43秒かかりました。
したがって、@ lzkataの暗黙の質問に答えるには、3.xでソートするためにcmp引数を削除することをお勧めします。
' System Down 'という名前のプログラマーが状況を正しく説明しています。Python 3の場合は、次のコードも使用できます。
Python 3の場合:
import functools
def greater(a, b):
if (a % b) % 2 == 0:
return 1
return -1
x = [2,7,5,10,30,15]
print(sorted(x, key=functools.cmp_to_key(greater)))