如何按第二项降序和第一项升序对列表进行排序?
How can i sort a list by the second item descending and first one ascending?
我有一个这样的列表:
list_results=[('Horror', 2), ('Romance', 2), ('Comedy', 2), ('History', 2), ('Adventure', 1), ('Action', 3)]
我希望按降序排列号码,如果号码相同,则按姓名升序排列。
我尝试了以下代码:
sortlist=sorted(list_results,key=lambda x:(x[1],x[0]))
反之亦然,但我不知道该怎么做。
我正在寻找的答案是:
[('Action', 3), ('Comedy', 2) ,('History', 2),('Horror', 2), ('Romance', 2), ('Adventure', 1), ]
首先按第一项排序列表,然后按第二项排序:
list_results = sorted(list_results, key=lambda x:x[0])
list_results = sorted(list_results, key=lambda x:x[1], reverse=True)
或者更好的是不复制:
import operator
list_results.sort(key=operator.itemgetter(0))
list_results.sort(key=operator.itemgetter(1), reverse=True)
Python 的排序算法是 Timsort. It is a stable algorithm,这意味着如果 2 个值相同,它们将保持原来的顺序。
如果先按字母顺序排序,然后按优先级排序,列表将按字母排序,然后按优先级重新排序,字母次之。
您想根据两个标准进行排序,其中一个标准充当另一个标准的决胜局。由于 python 的 sorted
和 list.sort
保证是稳定排序,一个解决方案是对列表进行两次排序:首先按平局排序,然后按主排序标准。
另一种可能性是只排序一次,使用元组作为键。 Python 的 sorted
和 list.sort
都提供了一个 reverse= True or False
参数来指定按升序或降序排序;但在您的情况下,我们希望根据第一个标准按降序排序,并根据第二个标准按升序排序。 reverse
关键字没有帮助,因为它是全有或全无:它不允许我们选择要反转的标准。
由于第一个标准是数字(整数),一个简单的逆序排序技巧是用减号取反:
sortlist = sorted(list_results, key=lambda x:(-x[1], x[0]))
注意 -x[1]
而不仅仅是 x[1]
。
这里有两个支持按元组排序一次而不是两次的论点:
- 按照
(-x[1], x[0])
排序时,马上就明白-x[1]
是主要标准,x[0]
只是一个平局。相比之下,如果你排序两次,阅读你的代码的人需要花一秒钟的时间来理解最后一次排序是最重要的,而前一次排序只是作为决胜局,依赖于 sorted
是稳定的排序。
- 如果列表很长,使用元组键排序一次可能比使用简单键排序两次更快。尤其如此,因为第二个键是一个字符串;比较字符串比比较整数慢。如果您使用元组,则只会比较在第一个键上相同的两个项目的字符串;但是如果你排序两次,大约
n log(n)
个字符串比较将在第一次排序中执行。
如果您的列表很小,那么哪个版本更快可能无关紧要(除非您重复对很多小列表进行排序...),所以这是一个偏好和可读性的问题。
我有一个这样的列表:
list_results=[('Horror', 2), ('Romance', 2), ('Comedy', 2), ('History', 2), ('Adventure', 1), ('Action', 3)]
我希望按降序排列号码,如果号码相同,则按姓名升序排列。
我尝试了以下代码:
sortlist=sorted(list_results,key=lambda x:(x[1],x[0]))
反之亦然,但我不知道该怎么做。
我正在寻找的答案是:
[('Action', 3), ('Comedy', 2) ,('History', 2),('Horror', 2), ('Romance', 2), ('Adventure', 1), ]
首先按第一项排序列表,然后按第二项排序:
list_results = sorted(list_results, key=lambda x:x[0])
list_results = sorted(list_results, key=lambda x:x[1], reverse=True)
或者更好的是不复制:
import operator
list_results.sort(key=operator.itemgetter(0))
list_results.sort(key=operator.itemgetter(1), reverse=True)
Python 的排序算法是 Timsort. It is a stable algorithm,这意味着如果 2 个值相同,它们将保持原来的顺序。
如果先按字母顺序排序,然后按优先级排序,列表将按字母排序,然后按优先级重新排序,字母次之。
您想根据两个标准进行排序,其中一个标准充当另一个标准的决胜局。由于 python 的 sorted
和 list.sort
保证是稳定排序,一个解决方案是对列表进行两次排序:首先按平局排序,然后按主排序标准。
另一种可能性是只排序一次,使用元组作为键。 Python 的 sorted
和 list.sort
都提供了一个 reverse= True or False
参数来指定按升序或降序排序;但在您的情况下,我们希望根据第一个标准按降序排序,并根据第二个标准按升序排序。 reverse
关键字没有帮助,因为它是全有或全无:它不允许我们选择要反转的标准。
由于第一个标准是数字(整数),一个简单的逆序排序技巧是用减号取反:
sortlist = sorted(list_results, key=lambda x:(-x[1], x[0]))
注意 -x[1]
而不仅仅是 x[1]
。
这里有两个支持按元组排序一次而不是两次的论点:
- 按照
(-x[1], x[0])
排序时,马上就明白-x[1]
是主要标准,x[0]
只是一个平局。相比之下,如果你排序两次,阅读你的代码的人需要花一秒钟的时间来理解最后一次排序是最重要的,而前一次排序只是作为决胜局,依赖于sorted
是稳定的排序。 - 如果列表很长,使用元组键排序一次可能比使用简单键排序两次更快。尤其如此,因为第二个键是一个字符串;比较字符串比比较整数慢。如果您使用元组,则只会比较在第一个键上相同的两个项目的字符串;但是如果你排序两次,大约
n log(n)
个字符串比较将在第一次排序中执行。
如果您的列表很小,那么哪个版本更快可能无关紧要(除非您重复对很多小列表进行排序...),所以这是一个偏好和可读性的问题。