如何为降序值编写Python排序键函数 [英] How to write Python sort key functions for descending values
问题描述
最近的Python版本中将 key 函数从以前的 cmp 函数传递给sort()
的举动,使我在某些情况下执行复杂的排序变得比较棘手对象.
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.
使用数字很容易(虽然很丑)-只是从某些东西中减去它们-但是我是否必须找到类似的日期破解方法(从另一个日期中减去它们并比较timedelta?)和字符串(... I不知道我如何以与语言环境无关的方式颠倒它们的顺序.
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的程序的过渡工具" .这意味着我应该可以使用key方法做我想做的事-但是怎么做?
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))
这篇关于如何为降序值编写Python排序键函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!