98 lines
3.2 KiB
Markdown
98 lines
3.2 KiB
Markdown
#领域/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()`(原地修改)减少内存占用 |