如何为降序编写排序键函数? [英] How to write sort key functions for descending values?
问题描述
最近版本的 Python 将 key 函数从之前的 cmp 函数传递给 sort()
me 对某些对象执行复杂的排序.
The move in recent versions of Python to passing a key function to sort()
from the previous cmp function is making it trickier for me to perform complex sorts on certain objects.
例如,我想将一组对象从最新到最旧排序,并使用一组字符串决胜局字段.所以我希望日期按相反顺序排列,但字符串按自然顺序排列.使用比较函数,我可以反转日期字段与字符串字段的比较.但是使用关键函数,我需要找到某种方法来反转/反转日期或字符串.
For example, I want to sort a set of objects from newest to oldest, with a set of string tie-breaker fields. So I want the dates in reverse order but the strings in their natural order. With a comparison function I can just reverse the comparison for the date field compared to the string fields. But with a key function I need to find some way to invert/reverse either the dates or the strings.
处理数字很容易(虽然丑陋) - 只需从某些东西中减去它们 - 但是我是否必须找到类似的日期黑客(从另一个日期中减去它们并比较时间增量?)和字符串(...我不知道如何以与语言环境无关的方式颠倒它们的顺序).
It's easy (although ugly) to do with numbers - just subtract them from something - but do I have to find a similar hack for dates (subtract them from another date and compare the timedeltas?) and strings (...I have no idea how I'd reverse their order in a locale-independent way).
我知道 functools.cmp_to_key()
的存在,但它被描述为 主要用作转换到 Python 3 的程序的过渡工具,其中比较函数不再支持".这意味着我应该能够用关键方法做我想做的事 - 但如何做?
I know of the existence of functools.cmp_to_key()
but it is described as being "primarily used as a transition tool for programs being converted to Python 3 where comparison functions are no longer supported". This implies that I should be able to do what I want with the key method - but how?
推荐答案
缓慢但优雅的方法是创建一个反向排序的值包装器:
The slow-but-elegant way to do this is to create a value wrapper that has reversed ordering:
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 个比较,例如:
If you don't have functools.total_ordering
, you'd have to implement all 6 comparisons, e.g.:
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))
这篇关于如何为降序编写排序键函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!