如何优化Python sort_people函数的排序性能?
问题:优化人员排序算法的性能
任务要求实现sort_people(people)函数,接收人员列表并返回排序后的列表,排序规则:
- 优先按出生日期从年长到年轻排序
- 出生日期相同时,按姓氏升序排序
- 姓氏也相同时,按名字升序排序
- 三项特征均一致时,顺序任意
我原本用functools.cmp_to_key配合自定义比较函数实现,但性能未达标,只拿到5/10分,需要优化排序速度。
我的代码:
import datetime import functools def compare_people(p1, p2): date1 = datetime.strptime(p1.birth_date, '%d.%m.%Y') date2 = datetime.strptime(p2.birth_date, '%d.%m.%Y') if date1>date2: return 1 elif date1<date2: return -1 if p1.last_name > p2.last_name: return 1 elif p1.last_name < p2.last_name: return -1 if p1.first_name > p2.first_name: return 1 elif p1.first_name < p2.first_name: return -1 else: return 0 def sort_people(people): cmp1 = functools.cmp_to_key(compare_people) people.sort(key=cmp1) return people
优化方案
你的代码性能瓶颈主要在两点:
cmp_to_key的效率远低于直接使用sort的key参数——比较函数会在每对元素对比时重复调用,时间复杂度为O(n²)级别的函数开销;而key函数仅为每个元素计算一次排序键,开销是O(n)级别。- 每次比较都重复调用
datetime.strptime解析日期,同一个日期会被解析多次,浪费大量计算资源。
优化后的基础版本
import datetime def sort_people(people): def get_sort_key(person): # 仅解析一次日期,转换为datetime对象 birth_date = datetime.strptime(person.birth_date, '%d.%m.%Y') # 排序键元组:(-日期序数, 姓氏, 名字) # 元组按顺序对比元素,完全匹配排序规则 return (-birth_date.toordinal(), person.last_name, person.first_name) # 使用key参数排序,性能远高于cmp_to_key people.sort(key=get_sort_key) return people
优化细节说明
- 预计算排序键:每个人员的日期仅解析一次,避免重复解析的冗余开销。
- 元组作为排序键:Python元组会按元素顺序依次比较,完美契合排序规则:
-birth_date.toordinal():将日期转换为整数序数后取负,让年长的日期(序数更小)排在前面。- 姓氏、名字直接按升序排列,当前面的元素相同时,自动用后续元素继续对比。
- 弃用cmp_to_key:直接使用
sort的key参数是Python排序的最优实践,数据量越大,性能提升越明显。
极致性能版本(跳过datetime解析)
如果数据量极大,还可以跳过datetime模块,直接拆分日期字符串生成排序键,进一步提升速度:
def sort_people(people): def get_sort_key(person): # 拆分日期字符串,转换为整数元组 day, month, year = person.birth_date.split('.') # 用(-年, -月, -日)实现日期降序,后续拼接姓氏、名字 return (-int(year), -int(month), -int(day), person.last_name, person.first_name) people.sort(key=get_sort_key) return people
这个版本完全避免了datetime解析的开销,仅通过字符串操作和整数转换生成排序键,性能会比基础版本更优。
内容的提问来源于stack exchange,提问作者some_guy256
相关产品推荐
相关产品推荐

