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

Python实现User对象列表先按name降序再按id升序排序

Python多字段不同排序方向实现方法

直接给sorted传单key加reverse=True/False只能统一控制所有排序字段的升降序,要实现不同字段对应不同排序方向,有3种常用写法,无需额外依赖:


方案1:利用稳定排序两次排序(通用首选,兼容所有字段类型)

Python内置的sorted是稳定排序:当两个元素的排序键相等时,会保留它们在排序前列表里的相对位置。利用这个特性,我们只要从低优先级到高优先级依次排序就行:

  • 需求里第二优先级是id升序,属于低优先级规则,先排
  • 第一优先级是name降序,属于高优先级规则,后排,排的时候传reverse=True实现倒序

修正后的完整可运行代码:

class User:
    def __init__(self, id, name):
        self.id = id
        self.name = name

def sorts(users):
    # 第一步:先按低优先级规则 id升序 排序
    users = sorted(users, key=lambda x: x.id)
    # 第二步:再按高优先级规则 name降序 排序,稳定排序会自动保留name相同元素的id升序顺序
    users = sorted(users, key=lambda x: x.name, reverse=True)

    for u in users:
        print(u.name, u.id)


# 测试数据,额外加了两个name为Andy的实例,用来验证id升序的第二规则
user1 = User(41, 'John')
user2 = User(32, 'Doe')
user3 = User(93, 'Mary')
user4 = User(412, 'Andrew')
user5 = User(54, 'Jesus')
user6 = User(62, 'Abigale')
user7 = User(37, 'Waldo')
user8 = User(18, 'Abby')
user9 = User(92, 'Andy')
user10 = User(10, 'Hulk')
user11 = User(117, 'Ron')
user12 = User(2, 'Andy')
user13 = User(100, 'Andy')

users= [user1, user2, user3 , user4 ,user5 ,user6 ,user7 ,user8, user9, user10, user11, user12, user13]
sorts(users)

运行后可以看到所有name从Z到A倒序排列,同名的Andy会按id从小到大(2、92、100)排列,完全符合需求。


方案2:单轮key转换(性能最好,仅适用于数值类降序字段)

如果需要降序的字段是数值类型,可以直接在key元组里对降序字段取负值,一次排序完成,性能比两次排序更高。但当前需求里需要降序的是字符串类型的name字段,这个方法不适用,举个适用场景的例子:如果需求是「id降序、name升序」,可以直接写:

# 降序的数值字段前面加负号即可
users = sorted(users, key=lambda x: (-x.id, x.name))

方案3:自定义比较函数(逻辑直观,适合复杂规则)

如果排序规则很复杂,没法简单通过key转换实现,可以用functools.cmp_to_key自定义比较逻辑:比较函数接收两个元素a、b,返回负数表示a排在b前面,返回正数表示b排在a前面,返回0表示两者相等。

from functools import cmp_to_key

def user_cmp(a, b):
    # 先判断name的降序规则
    if a.name > b.name:
        return -1
    elif a.name < b.name:
        return 1
    # name相等时走id升序规则
    else:
        return a.id - b.id

def sorts(users):
    users = sorted(users, key=cmp_to_key(user_cmp))
    for u in users:
        print(u.name, u.id)

这个方法的缺点是排序性能比key写法差,数据量特别大的时候不推荐用。

小提示:Python类名推荐用大驼峰命名,原来的user类名建议改成User,避免和循环变量、实例名重名引发bug。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:36:26