按多列排序时为每列设置升序或降序

3

我有一个列表d需要排序。首先按照第一列进行排序,如果第一列有相同值,则使用第二列进行排序。假设我想按照第一列升序排序,但按照第二列降序排序。默认情况下是升序,使用reverse关键字,我认为以下代码应该可以实现。

sorted(d,key=lambda x: (x[0],x[1]),reverse=(False,True))

但是它并没有成功。它会出现以下错误。
    reverse=(False,True))

TypeError: an integer is required (got type tuple)

如果我做错了,该怎么修正呢?或者说做这个的方法完全不同?关于这个问题的建议会很有帮助。

我的问题确实有些重复,但已经有了一些有趣的回答,所以我想保留它。


数值是数字吗?如果是,您可以使用否定来反转第二个元素的排序顺序:sorted(d,key=lambda x: (x[0],-x[1]))。如果您分享列表d的样本,将会很有帮助。 - pault
@pault 很好的观点。确实有些列可以是字符串。 - ztyh
3个回答

7

(可能有点过头了,但是..) 使用 pandas 和参数 ascending=[True, False]:


(说明:该段文字为提醒而非翻译内容)
d = [[1,2], [2,2], [2,3], [2,4], [3,1]]
df=  pd.DataFrame(d)

sorted_values = df.sort_values(by=[0,1], ascending=[True,False])
sorted_list = sorted_values.agg(list,1).tolist()

[[1, 2], [2, 4], [2, 3], [2, 2], [3, 1]]

1
这值得添加到规范问题中,我相信是这个 - pault
1
我已经按照你的建议@pault,谢谢 :) - rafaelc

1

来自文档:

reverse是一个布尔值。如果设置为True,则列表元素按照每个比较的相反顺序进行排序。

所以你想要的是这样的:

d.sort(key=lambda x: (x[0], -x[1]))

如果x[1]不是数字,请尝试:
d.sort(key=lambda x: x[1], reverse=True)
d.sort(key=lambda x: x[0])

1
如果 x[1] 是一个字符串呢? - pault
@pault 现在应该可以工作了... - minmax

1
我的解决方案如下:
from itertools import groupby, chain

l = ((1, 'b'),
     (1, 'd'),
     (2, 'a'),
     (1, 'a'))

def sort_multi(lst, index_normal, index_reversed):
    return list(chain.from_iterable([sorted(list(j), key=lambda v:v[index_reversed], reverse=True) for i, j in groupby(sorted(lst), key=lambda v:v[index_normal])]))


print(sort_multi(l, 0, 1))

输出:

[(1, 'd'), (1, 'b'), (1, 'a'), (2, 'a')]

@pault 已更正 - Andrej Kesely
看起来这个可以适用于2个索引 - 如果您能将其扩展到适用于任意数量的索引,那将非常有用。 - pault

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接