8

さまざまなコンパレータ機能を使って辞書の項目を並べ替えたい。以下のサンプルコードをご覧ください。動作しないsorted()でcmpRatio関数を使用する最後の部分です。何が間違っているのかわかりません。アイデアを事前に感謝します!

mydict = { 'a1': (1,6),
          'a2': (10,2),
          'a3': (5,3),
          'a4': (1,2),
          'a5': (3,9),
          'a6': (9,7) }

# sort by first element of the value tuple: WORKS
print sorted(mydict.iteritems(), key=lambda (k,v): v[0])

# sort by second element of the value tuple: WORKS
print sorted(mydict.iteritems(), key=lambda (k,v): v[1])

# THIS is what I can't get working:
def cmpRatio(x,y):
   sx = float(x[0])/x[1]
   sy = float(y[0])/y[1]
   return sx < sy

# sort by sum of the elements in the value tuple: DOES NOT WORK
print sorted(mydict.iteritems(), key=lambda (k,v): v, cmp=cmpRatio)
4

3 に答える 3

6

cmp関数は遅いので、可能な限り避けてください。比較するたびに再評価する必要があります。aを使用するkeyと、キーを1回だけ計算する必要があります。

print sorted(mydict.iteritems(), key=lambda (k,v): float(v[0])/v[1])

また、値アイテムの合計で並べ替えたいと言いますが、差で並べ替えています。合計は次のようになります。

print sorted(mydict.iteritems(), key=lambda (k,v): sum(v))

他の回答で述べたように、実際に関数を定義したいという目的のためにcmp、適切な値(-1,0、または1である必要があります)を返していません。

return cmp(sx,sy)

itemgetterただし、ラムダを使用して値を取得している場合は、Python側の関数よりも高速な値に置き換えることができます。

from operator import itemgetter

print sorted(mydict.iteritems(), key=itemgetter(1), cmp=cmpRatio)

並べ替え操作を保存しようとしている場合は、主要な機能を保存する方がはるかに優れています。

key_ops = {
    'sum': lambda (k,v): sum(v),
    'ratio': lambda (k,v): float(v[0])/v[1]),
}

def print_op(aDict, opName):
    print sorted(aDict.iteritems(), key=key_ops[opName])

... # some place later in code
print_op(mydict, 'sum')
于 2012-11-21T20:01:11.190 に答える
4

std::sort(...)比較関数は、最初の引数が2番目の値( C ++で指定されたコンパレータとは異なり)の場合(負/ゼロ/正)の値を返す必要があります。

すなわちの代わりに

return sx < sy

行う

return cmp(sx,sy)
于 2012-11-21T20:01:48.740 に答える
2

(コメントによると)値タプルの合計でソートする場合は、次を使用できます。

print sorted(mydict.iteritems(), key=lambda v: sum(v[1]))

(コードに応じて)比率で並べ替える場合:

print sorted(mydict.iteritems(), key=lambda v: float(v[1][0])/v[1][1])
于 2012-11-21T20:00:33.843 に答える