web-dev-qa-db-ja.com

タプルのリストを2番目の値、reverse = True、次にキー、reverse = Falseでソートします

最初に辞書をソートする必要があり、値はreverse=True、および値の繰り返しの場合は、キーで並べ替え、reverse=False

これまでのところ、私はこれを持っています

dict = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(dict.items(), key=lambda x: (x[1],x[1]), reverse=True)

戻る...

[('B', 3), ('A', 2), ('J', 1), ('I', 1), ('A', 1)]

しかし、私はそれが必要です:

[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

ご覧のとおり、値が等しい場合、指定されたとおりにキーを減少させる方法でのみソートできます...しかし、増加する方法でソートするにはどうすればよいですか?

27
Nicolas Hung

以下はあなたの入力で動作します:

d = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(d,key=lambda x:(-x[1],x[0]))

「値」は数値であるため、符号を変更することで簡単にソート順を逆にすることができます。

言い換えれば、このソートは、値(-x[1])(負符号は大きな数字を最初に置きます)、次に同じ数字の場合、キー(x[0])。

値を「否定」して大きなアイテムを最初に配置できない場合、簡単な回避策は2回ソートすることです。

from operator import itemgetter
d.sort(key=itemgetter(0))
d.sort(key=itemgetter(1),reverse=True)

これは、Pythonのソートが安定しているため機能します。

41
mgilson
In [4]: l = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

In [5]: sorted(l, key=lambda (x,y):(-y,x))
Out[5]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
3
NPE

_collections.defaultdict_を使用できます:

_In [48]: from collections import defaultdict

In [49]: dic=[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

In [50]: d=defaultdict(list)

In [51]: for x,y in dic:
    d[y].append(x)
    d[y].sort()          #sort the list
_

dは次のようになります。

_ defaultdict(<type 'list'>, {1: ['A', 'I', 'J'], 2: ['A'], 3: ['B']}
_

つまり、キーとして_1,2,3..._を持ち、値としてリストに保存された対応するアルファベットを持つ新しいdict

これで、sorted(d.items)を反復処理し、itertools.chain()およびitertools.product()を使用して目的の結果を取得できます。

_In [65]: l=[ product(y,[x]) for x,y in sorted(d.items(),reverse=True)]

In [66]: list(chain(*l))
Out[66]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
_
1