首页 文章

使用不同的顺序按多个键排序[重复]

提问于
浏览 1712 次
32

可能重复:如何为降序值编写Python排序键函数

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

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

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

例如,假设我们有一个具有两个属性的对象 pointsname ,其中 pointsintnamestr . 我们希望按 points 按降序对这些对象的列表进行排序(以便具有最大点数的对象首先出现),但是对于具有相同数量的 points 的对象,我们希望按字母顺序排列 name (升序)订单 .

怎么能实现这一目标?

3 回答

  • 22

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

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

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

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

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

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

相关问题