一尘不染

如何为降序值编写Python排序键函数

python

在Python的最新版本中,将 函数传递到sort()以前的 cmp 函数的举动,使我对某些对象执行复杂的排序变得更加棘手。

例如,我想用一组字符串平局决胜者字段对一组对象从最新到最旧进行排序。因此,我希望日期按相反的顺序排列,但字符串按其自然顺序排列。使用比较功能,我可以将日期字段与字符串字段的比较结果取反。但是,通过键功能,我需要找到某种方法来反转/反转日期或字符串。

处理数字很容易(虽然很丑)-只是从某些东西中减去它们-
但是我是否必须找到类似的日期破解方法(从另一个日期中减去它们并比较timedelta?)和字符串(…我不知道如何以与语言环境无关的方式颠倒它们的顺序)。

我知道functools.cmp_to_key()它的存在,但是它被描述为 “主要用作转换为不再支持比较功能的Python 3的程序的转换工具”
。这意味着我应该能够使用密钥方法做我想做的事情-但是怎么做?


阅读 100

收藏
2020-12-20

共1个答案

一尘不染

缓慢但优雅的方法是创建一个具有相反顺序的值包装器:

from functools import total_ordering
@total_ordering
class ReversedOrder:
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        return other.value == self.value
    def __lt__(self, other):
        return other.value < self.value

如果没有functools.total_ordering,则必须实施所有6个比较,例如:

import operator
class ReversedOrder:
    def __init__(self, value):
        self.value = value
for x in ['__lt__', '__le__', '__eq__', '__ne__', '__ge__', '__gt__']:
    op = getattr(operator, x)
    setattr(ReversedOrder, x, lambda self, other, op=op: op(other.value, self.value))
2020-12-20