このような名前の質問がいくつかあることは知っていますが、彼らの答えが機能するようには思えません。
リストのリストがあり、50の5つの要素があります。次に、カスタム比較関数を各要素に適用して、このリストをソートします。この関数は、要素をソートするリストの適合度を計算します。比較とフィットネスの2つの関数を作成しました。
def compare(item1, item2):
return (fitness(item1) < fitness(item2))
そして
def fitness(item):
return item[0]+item[1]+item[2]+item[3]+item[4]
それから私はそれらを呼び出すことを試みました:
sorted(mylist, cmp=compare)
または
sorted(mylist, key=fitness)
または
sorted(mylist, cmp=compare, key=fitness)
または
sorted(mylist, cmp=lambda x,y: compare(x,y))
また、同じパラメーターでlist.sort()を試しました。ただし、いずれの場合でも、関数は引数としてリストを取得するのではなく、None
を取得します。それがなぜなのか、私にはわからない。ほとんどがC++から来ているので、これは私のコールバック関数の考えと矛盾する。このリストをカスタム関数でソートするにはどうすればよいですか?
編集間違いを見つけました。元のリストを作成するチェーンでは、1つの関数は何も返さず、戻り値が使用されました。わざわざごめんなさい
>>> l = [list(range(i, i+4)) for i in range(10,1,-1)]
>>> l
[[10, 11, 12, 13], [9, 10, 11, 12], [8, 9, 10, 11], [7, 8, 9, 10], [6, 7, 8, 9], [5, 6, 7, 8], [4, 5, 6, 7], [3, 4, 5, 6], [2, 3, 4, 5]]
>>> sorted(l, key=sum)
[[2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9, 10], [8, 9, 10, 11], [9, 10, 11, 12], [10, 11, 12, 13]]
上記は機能します。別のことをしていますか?
キー関数はsum
であることに注意してください。明示的に記述する必要はありません。
また、比較関数が正しくありません。ブール値ではなく、-1、0、または1を返す必要があります。正しい比較関数は次のとおりです。
def compare(item1, item2):
if fitness(item1) < fitness(item2):
return -1
Elif fitness(item1) > fitness(item2):
return 1
else:
return 0
compare
関数をわずかに変更し、functools.cmp_to_key
を使用してsorted
に渡す必要があります。サンプルコード:
import functools
lst = [list(range(i, i+5)) for i in range(5, 1, -1)]
def fitness(item):
return item[0]+item[1]+item[2]+item[3]+item[4]
def compare(item1, item2):
return fitness(item1) - fitness(item2)
sorted(lst, key=functools.cmp_to_key(compare))
出力:
[[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]]
作品:)
OPがカスタム比較関数の使用を求めていたので(そして、これがこの質問につながった理由でもあります)、ここでしっかりした答えをしたいと思います。
通常、カスタムコンパレータをパラメータとして使用する組み込みsorted()
関数を使用します。 Python 3ではパラメーター名とセマンティクスが変更されたという事実に注意する必要があります。
カスタムコンパレータを提供する場合、通常、次のパターンに従う整数/浮動小数点値を返す必要があります(他のほとんどのプログラミング言語およびフレームワークと同様)。
< 0
_)を返しますbefore右の項目> 0
_)を返します後右の項目0
_を返しますOPの質問の特定のケースでは、次のカスタム比較関数を使用できます。
_def compare(item1, item2):
return fitness(item1) - fitness(item2)
_
マイナス操作の使用は、左のアイテム(ここでは_item1
_)の重量が右のアイテム(ここでは_item2
_)の重量よりも大きいときに正の値になるため、巧妙なトリックです。したがって、item1はitem2の後にソートされます。
ソート順を逆にする場合は、単純に減算を逆にします:return fitness(item2) - fitness(item1)
_sorted(mylist, key=cmp(compare))
_
または:
_sorted(mylist, cmp=lambda item1, item2: fitness(item1) - fitness(item2))
_
_from functools import cmp_to_key
sorted(mylist, key=cmp_to_key(compare))
_
または:
_from functools import cmp_to_key
sorted(mylist, key=cmp_to_key(lambda item1, item2: fitness(item1) - fitness(item2)))
_