按不同元素对Python列表进行数字降序排序,然后按字母升序排序。

4

我有一个列表,其中包含三个元素,格式如下:

[('ABC', 'DEF', 2), ('GHI', 'JKL', 6), ('MNO', 'PQR', 22), ('ABC', 'STU', 2)...]

我希望按照最后一个元素的数字大小排序,然后按照第一个元素的字母顺序排序,最后如果有相等的情况再按照第二个元素排序。因此我的输出将是:
[('MNO', 'PQR', 22), ('GHI', 'JKL', 6), ('ABC', 'DEF', 2), ('ABC', 'STU', 2)...]

我已经尝试过。
list_name.sort(reverse=True, key=lambda x: x[2])

这只能按照最后一个元素降序排序。我该如何实现按字母顺序排序第一和第二个元素的功能?
2个回答

7
返回一个元组,而不是使用reverse来取反数字:
list_name.sort(key=lambda x: (-x[2],) + x[:2])

这将返回 (-item3, item1, item2) 并且排序首先按整数item3进行,以降序排序,当数字排序相同时,按字母表顺序对item1进行排序(升序),然后对item2进行排序。

实际上,元组是按字典序排序的。

演示:

>>> list_name = [('ABC', 'DEF', 2), ('GHI', 'JKL', 6), ('MNO', 'PQR', 22), ('ABC', 'STU', 2)]
>>> list_name.sort(key=lambda x: (-x[2],) + x[:2])
>>> list_name
[('MNO', 'PQR', 22), ('GHI', 'JKL', 6), ('ABC', 'DEF', 2), ('ABC', 'STU', 2)]

这将按降序对元素1和2进行排序,我需要第一个和第二个元素按升序排列,第三个元素按降序排列。 - user3466469
1
不,元素1和2是按升序排序的。请注意所产生的输出。我已经说明您需要删除reverse参数。 - Martijn Pieters
1
元素 0 之所以按降序排序,是因为该数字被取反;-22 在 -6 和 -2 之前排序。 - Martijn Pieters

-2

将所有内容转换为字符串,然后进行比较即可。

list_name.sort(reverse=True, key=lambda x: '%6d%s%s'%(x[2],x[0],x[1]) )

这将使109之后排序(按字典顺序而不是数字顺序),并按降序对元素1和2进行排序。 - Martijn Pieters
实际上不会。这就是为什么我们在前面加零的原因。 - ssm
好的,那么它将在9之后对1000000进行排序。使用元组时不需要使用字符串,而且您仍然以错误的顺序对另外两个组件进行排序。 - Martijn Pieters
通过从列表中最大值中减去数字值,很容易地反转数字值的顺序。例如,maxVal = numpy.array([x[2] for x in list_name]).max()'%6d%s%s'%((maxVal-x[2]),x[0],x[1]) - ssm
1
对于“容易”的给定值,你将复杂度从O(NlogN)增加到了O(2NlogN),当然。 - Martijn Pieters
而且,为了跟进这个问题,你还假设所有的字符串长度都相等;如果它们不相等,那么连接它们将导致完全不同的排序结果。是的,你可以填充它们,但你只会发现越来越多的边缘情况(例如支持控制字节),这些情况都可以通过从排序键函数返回一个元组来完全避免。 - Martijn Pieters

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