You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用比较函数多键排序:如何仅对单个键进行逆序排序?

Python 3 实现多属性独立升降序排序(非数值属性)

核心解决思路:用functools.cmp_to_key兼容Python 2风格比较函数

Python 3 确实移除了sort()直接传入比较函数的接口,但可以借助functools模块的cmp_to_key工具,把Python 2风格的自定义比较函数转换成sort()能识别的key参数,以此实现对每个属性单独控制升降序的需求,完全适配非数值类型属性。

示例代码演示

假设我们有一个Person类,包含name(字符串)、status(枚举类型,比如Status.ACTIVE/Status.INACTIVE)两个非数值属性,需求是:按status降序排列,status相同时按name升序排列。

from functools import cmp_to_key
from enum import Enum

class Status(Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"

class Person:
    def __init__(self, name, status):
        self.name = name
        self.status = status

    def __repr__(self):
        return f"Person(name='{self.name}', status={self.status.name})"

# 自定义比较函数,逻辑和Python 2一致
def compare_persons(a, b):
    # 先处理status的降序逻辑
    if a.status != b.status:
        # 按业务规则,ACTIVE优先级高于INACTIVE,降序时让ACTIVE排在前面
        return -1 if a.status == Status.ACTIVE else 1
    # status相同时,处理name的升序逻辑
    if a.name < b.name:
        return -1
    elif a.name > b.name:
        return 1
    else:
        return 0

# 测试数据
people = [
    Person("Bob", Status.INACTIVE),
    Person("Alice", Status.ACTIVE),
    Person("Charlie", Status.ACTIVE),
    Person("David", Status.INACTIVE)
]

# 用cmp_to_key转换比较函数后传入sort
people.sort(key=cmp_to_key(compare_persons))
print(people)
# 输出结果: [Person(name='Alice', status=ACTIVE), Person(name='Charlie', status=ACTIVE), Person(name='Bob', status=INACTIVE), Person(name='David', status=INACTIVE)]

关键说明

  • 自定义比较函数的逻辑和Python 2完全一致:返回-1表示a应排在b前面,返回1表示b应排在a前面,返回0表示两者排序优先级相同。
  • 针对非数值属性,可直接根据业务规则定义比较逻辑,比如枚举值的优先级、字符串的字典序等,无需依赖取反操作。
  • cmp_to_key的性能略低于直接使用key参数,但对于绝大多数业务场景,这个性能差异可以忽略不计。

备选方案:为非数值属性映射可排序键

如果不想使用比较函数,也可以为非数值属性映射一个可排序的量化值,比如给status分配权重:

def get_sort_key(person):
    # 给status分配权重,ACTIVE权重2、INACTIVE权重1,用负权重实现降序
    status_weight = 2 if person.status == Status.ACTIVE else 1
    # 元组排序时会依次比较元素,这里先按负权重降序,再按name升序
    return (-status_weight, person.name)

people.sort(key=get_sort_key)

这种方式性能更优,但需要为每个非数值属性设计合理的映射规则,适合排序规则固定且容易量化的场景。

内容的提问来源于stack exchange,提问作者Hays Jedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:52:11