【python基础包functools的cmp_to_key, 比较方法和关键方法-亢保星-哔哩哔哩】
sorted(): 内置函数,返回新的排序列表,不改变原序列list.sort(): 列表方法,原地排序,返回 None,改变原列表sorted() 的情况:list.sort() 的情况:# 按字符串长度排序
words = ['apple', 'banana', 'cherry', 'date']
sorted_words = sorted(words, key=len) # ['date', 'apple', 'banana', 'cherry']
# 按字典的某个值排序
students = [{'name': 'Alice', 'grade': 90}, {'name': 'Bob', 'grade': 85}]
sorted_students = sorted(students, key=lambda x: x['grade'], reverse=True)# 先按年龄升序,再按分数降序
data = [('Alice', 25, 88), ('Bob', 25, 92), ('Charlie', 23, 95)]
sorted_data = sorted(data, key=lambda x: (x[1], -x[2]))from operator import itemgetter, attrgetter
# 按元组第二个元素排序
sorted([(1, 2), (3, 1), (5, 0)], key=itemgetter(1))
# 按对象属性排序
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
people = [Person('Alice', 25), Person('Bob', 20)]
sorted_people = sorted(people, key=attrgetter('age'))Python 的排序是稳定的,意味着相等元素的相对顺序保持不变:
data = [('red', 1), ('blue', 1), ('red', 2)]
# 按第二个元素排序后,两个红色元素的相对顺序保持不变
sorted_data = sorted(data, key=lambda x: x[1])from functools import cmp_to_key
def compare(a, b):
if a % 2 == b % 2:
return a - b
return -1 if a % 2 else 1
numbers = [1, 2, 3, 4, 5, 6]
sorted_numbers = sorted(numbers, key=cmp_to_key(compare))
# 结果: [1, 3, 5, 2, 4, 6] (奇数在前,偶数在后,各自升序)# 将 None 值放在最后
data = [1, None, 3, 2, None]
sorted_data = sorted(data, key=lambda x: (x is None, x))Python 在比较元组时,会 从左到右逐元素比较:
x is None(False < True)x is None 相同(即都是 False 或都是 True),再比较 x 本身。None 的元素:(False, x)False 排序(比 True 小),然后按 x 排序。None 的元素:(True, None)True 比 False 大,所以 None 会排在最后。对于复杂对象的排序,预先计算键可以提升性能:
# 普通方式
sorted_data = sorted(data, key=lambda x: x.some_expensive_operation())
# 优化方式 - 预先计算
decorated = [(x.some_expensive_operation(), x) for x in data]
decorated.sort()
sorted_data = [x for (key, x) in decorated]选择 sort() 还是 sorted() 主要取决于是否需要保留原序列以及内存考虑。高级排序技巧可以处理复杂的数据结构排序需求,通过合理使用 key 参数和比较函数,可以实现几乎任何自定义排序逻辑。