#领域/Python ## 一句话描述 [__Python 核心排序方法(sorted () 与 list.sort ())的特性对比、基础用法、自定义排序规则及性能优化技巧______] ## 核心定义 围绕核心排序方法 `sorted()` 和 `list.sort()` 的实现,二者核心特性对比如下: |特性|sorted(iterable)|list.sort()| |---|---|---| |返回值|返回**新的排序后列表**,原数据保持不变|无返回值(None),**原地修改**原列表| |适用对象|所有可迭代对象(列表、元组、字典等)|仅列表(list)类型| |内存占用|占用额外内存(生成新列表)|无额外内存消耗(原地修改)| |常用场景|需保留原数据、非列表对象的排序需求|无需保留原数据、仅针对列表的排序场景| ## 基础排序用法 ```python # sorted():生成新列表 nums = [3, 1, 2] new_nums = sorted(nums) # new_nums=[1,2,3], nums仍为[3,1,2] # list.sort():原地修改 nums.sort() # nums变为[1,2,3],返回None ``` ## 自定义排序规则 ### 1. key 参数(lambda / 自定义函数) - 单维度排序:`key=lambda 元素: 元素.属性` - 多维度排序:`key=lambda 元素: (属性1, 属性2)`(优先按属性 1,相等则按属性 2) ```python # 优先x升序 → 其次y升序(你的核心需求) sorted_list = sorted(msg_list, key=lambda m: (m.x, m.y)) # 反向:优先x降序 → 其次y降序 sorted_list_rev = sorted(msg_list, key=lambda m: (m.x, m.y), reverse=True) # 更复杂场景:x升序,y降序(混合方向) sorted_list_mix = sorted(msg_list, key=lambda m: (m.x, -m.y)) # -y实现y降序 ``` ### 重写类的比较方法(**lt**) 如果某个类的排序规则是 “长期固定” 的,可重写类的`__lt__`(小于)方法,Python 排序会自动基于`<`推导其他比较逻辑,无需指定`key`。 ```python class Msg: # x, y 属性 # 定义“小于”规则:先比x,再比y def __lt__(self, other): if not isinstance(other, Msg): # 避免类型错误,提升健壮性 return NotImplemented if self.x != other.x: return self.x < other.x return self.y < other.y # 直接排序,无需key sorted_list = sorted(msg_list) ``` ## 性能优化技巧 ### 提前排序键 对于大规模数据(万级以上),提前提取排序键(避免重复计算) ```python # 先生成(键, 对象)元组列表,排序后提取对象(减少属性访问次数) key_obj = [( (m.x, m.y), m ) for m in msg_list] key_obj.sort() sorted_list = [obj for (key, obj) in key_obj] ``` 避免在`key`中使用复杂计算(如函数调用),优先预计算。 ### operator 替代 lambda 内置的 `operator.attrgetter` 更简洁、大规模数据下性能更好(底层是 C 实现) ```python # 等价于 lambda m: (m.x, m.y),但更快、更简洁 sorted_list = sorted(msg_list, key=attrgetter("x", "y")) print(sorted_list)  # [Msg(i=2, x=1, y=3), Msg(i=3, x=2, y=1), Msg(i=1, x=3, y=2)] # 反向排序(x降→y升) sorted_rev = sorted(msg_list, key=attrgetter("x", "y"), reverse=True) ``` ### 注意事项 - 避免在 `key` 中使用复杂函数调用,优先通过预计算简化排序键 - 大规模数据排序时,优先选择 `list.sort()`(原地修改)减少内存占用