python-3.x 使用比较函数对多个键排序-如何只对一个键进行反向操作?[duplicate]

von4xj4u  于 2023-03-09  发布在  Python
关注(0)|答案(2)|浏览(160)

此问题在此处已有答案

How to sort a list with two keys but one in reverse order?(8个答案)
8小时前关门了。
在Python 3中,sort()有参数keyreverse。如果你使用一个自定义的比较函数,并且它对多个项排序(每个对象),你如何单独地对每个项进行升序或降序?在我的例子中,项不是数字,所以否定一个值不是一个选项。
我没有找到任何语法方法来做我想做的事情,所以我卡住了。在Python 2中,你可以很容易地做到这一点,因为比较函数返回-10+1。Python 3似乎不太灵活。

jtjikinw

jtjikinw1#

可以使用functools.cmp_to_key()函数:
将旧式比较函数转换为键函数。用于接受键函数的工具(如sorted()min()max()heapq.nlargest()heapq.nsmallest()itertools.groupby())。此函数主要用作从支持使用比较函数的Python 2转换而来的程序的转换工具。
也就是说,您可以转换以下Python 2代码:

mylist.sort(cmp=my_comparator_function)

转换为Python 3,如下所示

from functools import cmp_to_key

mylist.sort(key=cmp_to_key(my_comparator_function))
flseospp

flseospp2#

更新:这不是一个好的方法。我不会删除答案,因为评论中的讨论很有价值。

重要提示:只有在可以修改要比较的对象的定义时,这种方法才适用。
如果你有访问对象定义的权限并且允许修改它,你可以覆盖对象中的dunder方法__lt__来规定如何进行比较。因为你设置了比较规则,所以你可以按照你想要的方式排序,而不必为排序函数提供key

示例

class ObjectToCompare:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __lt__(self, other):
        if self.a < other.a:
            return True
        if self.b > other.b:
            return True

    def __repr__(self):
        # this is just for printing purpose
        # it has nothing to do with sorting
        return f'({self.a}, {self.b})'

lst = [
    ObjectToCompare(2, 'a'),
    ObjectToCompare(2, 'b'),
    ObjectToCompare(1, 'a'),
    ObjectToCompare(1, 'c'),
]

print(sorted(lst))

# output:
# [(1, c), (1, a), (2, b), (2, a)]

解释

Foo的示例首先按a升序排序。如果a(整数)相同,则按b(字符串)降序排序。此逻辑在__lt__方法中表示。

相关问题