按第二个值对元组列表进行排序,reverse=True,然后按 key,reverse=False

Posted

技术标签:

【中文标题】按第二个值对元组列表进行排序,reverse=True,然后按 key,reverse=False【英文标题】:Sort a list of tuples by second value, reverse=True and then by key, reverse=False 【发布时间】:2013-01-06 03:02:35 【问题描述】:

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

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

【问题讨论】:

dict 是一个列表——甚至不是一个真正适合变成字典的列表,因为它会有重复的键...... 感谢 mgilson 让它工作,我正在尝试类似的东西,但很困,无法思考。谢谢! 【参考方案1】:

以下内容适用于您的输入:

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的排序是稳定的。

【讨论】:

如上例,如果使用itemgetter方法,则优先级倒序:d.sort(...) d.sort(...) d.sort(...) itemgetter 部分错误,@Lorenz 点有效【参考方案2】:
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】:

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

即一个新的dict,其中1,2,3... 作为键,对应的字母作为值存储在列表中。

现在您可以遍历 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)]

【讨论】:

我不太确定你在这里展示的是什么......你可能应该提供更多解释:P

以上是关于按第二个值对元组列表进行排序,reverse=True,然后按 key,reverse=False的主要内容,如果未能解决你的问题,请参考以下文章

按第二项(整数值)对元组列表进行排序[重复]

如何按第一个值和第二个值对 pair<int, char> 的向量进行排序? [复制]

按元组的第二个元素对元组列表进行排序,无需高阶函数或递归

在Prolog中的元组列表中按降序排序

如何按 Int 值对元组数组进行排序?

如何按第二个单词对列表进行排序? [复制]