使用不同的顺序按多个键排序

时间:2012-07-13 18:38:39

标签: python python-3.x

  

可能重复:
  How to write Python sort key functions for descending values

在Python 3中,使用多个键按字典顺序对对象列表进行排序非常容易。例如:

items.sort(key = lambda obj: obj.firstname, obj.lastname)

reverse参数允许您指定是升序还是降序。但是,如果您想按多个键排序,但是想要使用第一个键的降序排序,以及第二个键的升序排序,您会怎么做?

例如,假设我们有一个包含两个属性pointsname的对象,其中pointsintname是{{} 1}}。我们希望按<{1>}以降序顺序对这些对象的列表进行排序(以便具有最多点数的对象首先出现),但对于具有相同数量{{ 1}},我们希望按字母顺序(升序)顺序按str排序。

如何实现这一目标?

3 个答案:

答案 0 :(得分:28)

没有内置的方法来处理这个问题。对于一般情况,您必须排序两次:首先是二级排序,然后是主排序。正如@Mark Ransom在他的评论中提到的,在很多情况下变量是数字的,所以你可以使用负值来翻转排序。

如果您知道要尝试排序的变量的类型以及如何使用它,您还可以编写一个键函数,该函数返回递增键的递减值。有关字符串的示例,请参阅this thread。 (基本上,你取字符的ASCII数值的负数。)

在Python 2中,您还可以使用cmp函数而不是键,但这可能会使排序变慢。是否会使它太慢取决于列表的大小和未分类。在Python 3中,cmp参数消失了,但正如@Mark Ransom所说,你可以使用cmp_to_key

答案 1 :(得分:12)

items.sort(key = lambda obj: (obj.firstname, [(-ord(c) for c in obj.lastname)]))

答案 2 :(得分:6)

functools.cmp_to_key将比较函数转换为与排序函数兼容的密钥。这是为在Python 2中使用比较函数的类别提供的,需要转换为不再允许它们的Python 3。

编辑:在Python wiki的标题Sort Stability and Complex Sorts下也有一个建议,可以在多次传递中进行排序,从最不重要的密钥到最重要的密钥。这是有效的,因为Python的排序保证是稳定的,因此在遇到等效键时会保留先前的顺序。

相关问题