36

我需要首先对字典进行排序,使用 的值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)]

如您所见,当值相等时,我只能按照指定的递减方式对键进行排序......但是我怎样才能让它们以递增的方式排序?

4

3 回答 3

59

以下适用于您的输入:

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

由于您的“值”是数字,因此您可以通过更改符号轻松地反转排序顺序。

换句话说,这种排序按值(-x[1])排序(负号将大数放在首位),然后对于相同的数字,它根据键(x[0])排序。

如果您的价值观不能轻易被“否定”以将大项目放在首位,那么一个简单的解决方法是排序两次:

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

之所以有效,是因为 python 的排序是稳定的。

于 2013-01-22T19:08:55.393 回答
4
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)]
于 2013-01-22T19:09:19.953 回答
2

你可以使用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']}

即一个新dict1,2,3...作为键和相应的字母存储在列表中作为值。

现在您可以使用and遍历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)]
于 2013-01-22T19:14:44.763 回答