Python函数:sorted()排序函数与自定义排序规则

发布时间:2026/9/13 23:22:09

Python函数:sorted()排序函数与自定义排序规则 Python函数sorted()排序函数与自定义排序规则一、开篇排序——数据处理的基本功排序是编程中最常见的操作之一。Python提供了两个排序工具list.sort()原地排序和sorted()返回新排序结果。其中sorted()更灵活、更通用——它能排序任何可迭代对象还能自定义排序规则。⌨️ 先看最基础的用法# sorted()的基本用法numbers[3,1,4,1,5,9,2,6]sorted_numberssorted(numbers)print(sorted_numbers)# [1, 1, 2, 3, 4, 5, 6, 9]print(numbers)# [3, 1, 4, 1, 5, 9, 2, 6] ← 原列表不变# list.sort()——原地排序直接修改原列表numbers.sort()print(numbers)# [1, 1, 2, 3, 4, 5, 6, 9] ← 被修改了# 关键区别# sorted(iterable) → 返回新列表原数据不变可用于任何可迭代对象# list.sort() → 原地排序不返回新列表只能用于列表sorted()的核心优势在于它的key参数——让你能按任意规则排序这个参数是Python排序系统的灵魂。二、sorted()的基本参数2.1 三个参数详解# sorted(iterable, keyNone, reverseFalse)# iterable: 要排序的可迭代对象# key: 排序依据的函数接收每个元素返回用于比较的值# reverse: 是否降序True降序False升序# reverse参数——升降序控制numbers[3,1,4,1,5]print(sorted(numbers))# [1, 1, 3, 4, 5] 升序print(sorted(numbers,reverseTrue))# [5, 4, 3, 1, 1] 降序# key参数——自定义排序依据words[banana,apple,Cherry,date,Elderberry]# 默认排序——按Unicode码点大写字母在小写字母前print(sorted(words))# [Cherry, Elderberry, apple, banana, date]# 按字母顺序忽略大小写print(sorted(words,keystr.lower))# [apple, banana, Cherry, date, Elderberry]# 按单词长度排序print(sorted(words,keylen))# [date, apple, banana, Cherry, Elderberry]2.2 key参数的详解# key函数的规则# 1. key接收一个参数序列中的每个元素# 2. key返回一个用于比较的值# 3. 排序根据key的返回值进行不是原始元素# 4. 原始元素不变——只是排序的依据变了# 绝对值排序numbers[-5,3,-1,4,-2]print(sorted(numbers,keyabs))# [-1, -2, 3, 4, -5]# 按字符串中数字的大小排序codes[item2,item10,item1,item20]print(sorted(codes))# [item1, item10, item2, item20] ← 字典序item10在item2前importredefextract_number(s):提取字符串中的数字matchre.search(r\d,s)returnint(match.group())ifmatchelse0print(sorted(codes,keyextract_number))# [item1, item2, item10, item20] ← 按数字大小排# 按时间排序times[2024-03-15,2023-12-01,2024-01-20,2023-06-10]print(sorted(times))# 字符串比较恰好对日期格式有效# [2023-06-10, 2023-12-01, 2024-01-20, 2024-03-15]三、lambda作为key——最常用的排序方式3.1 按字典字段排序# ⌨️ 排序字典列表——职场中最常用的技能employees[{name:张三,age:28,salary:15000,department:技术部},{name:李四,age:35,salary:20000,department:管理部},{name:王五,age:22,salary:12000,department:技术部},{name:赵六,age:30,salary:18000,department:市场部},{name:钱七,age:25,salary:13000,department:技术部},]# 按年龄排序by_agesorted(employees,keylambdae:e[age])print(按年龄,[e[name]foreinby_age])# [王五, 钱七, 张三, 赵六, 李四]# 按薪资降序by_salarysorted(employees,keylambdae:e[salary],reverseTrue)print(按薪资降序,[(e[name],e[salary])foreinby_salary])# [(李四, 20000), (赵六, 18000), (张三, 15000), (钱七, 13000), (王五, 12000)]# 按年龄排序同年龄按薪资降序多级排序by_age_salarysorted(employees,keylambdae:(e[age],-e[salary]))print(年龄薪资,[(e[name],e[age],e[salary])foreinby_age_salary])3.2 多级排序# 多级排序key返回一个元组# Python按元组的元素顺序依次比较# 先按部门再按薪资降序resultssorted(employees,keylambdae:(e[department],-e[salary]))foreinresults:print(f{e[department]}-{e[name]}: ¥{e[salary]})# 管理部 - 李四: ¥20000# 技术部 - 张三: ¥15000# 技术部 - 钱七: ¥13000# 技术部 - 王五: ¥12000# 市场部 - 赵六: ¥18000# 技巧降序字段用负号# 数字降序-e[salary]注意这只对数字有效# 字符串降序没法用负号需要分两次排序或用functools.cmp_to_key# 多级排序的另一种方法多次sorted()利用稳定性# Python的排序是稳定的——相同key的元素保持原来的相对顺序# 先按次要key排再按主要key排resultsorted(employees,keylambdae:e[salary],reverseTrue)resultsorted(result,keylambdae:e[department])# 结果同一部门内按薪资降序四、高级排序技巧4.1 使用operator模块fromoperatorimportitemgetter,attrgetter,methodcaller# itemgetter——获取字典的指定字段相当于lambda e: e[key]# 比lambda稍快一些而且更简洁by_departmentsorted(employees,keyitemgetter(department))print([e[department]foreinby_department])# itemgetter多级排序by_dept_salarysorted(employees,keyitemgetter(department,salary))# attrgetter——获取对象的属性classStudent:def__init__(self,name,score):self.namename self.scorescore students[Student(Alice,85),Student(Bob,92),Student(Charlie,78),]by_scoresorted(students,keyattrgetter(score),reverseTrue)forsinby_score:print(f{s.name}:{s.score})4.2 自定义对象的排序fromfunctoolsimporttotal_ordering# 方法一实现比较方法classTask:def__init__(self,name,priority,due_date):self.namename self.prioritypriority self.due_datedue_datedef__lt__(self,other):小于比较先按priority再按due_dateifself.priority!other.priority:returnself.priorityother.priorityreturnself.due_dateother.due_datedef__repr__(self):returnfTask({self.name}, pri{self.priority}, due{self.due_date})tasks[Task(写报告,2,2024-06-15),Task(修复Bug,1,2024-06-10),Task(开会,2,2024-06-12),Task(代码审查,1,2024-06-08),]print(sorted(tasks))# [Task(代码审查, pri1, due2024-06-08), Task(修复Bug, pri1, due2024-06-10),# Task(开会, pri2, due2024-06-12), Task(写报告, pri2, due2024-06-15)]# 方法二使用key更灵活不修改类tasks_sortedsorted(tasks,keylambdat:(t.priority,t.due_date))五、实战案例5.1 日志按时间排序# 场景排序杂乱的日志条目logs[[2024-03-15 14:30:22] ERROR 数据库连接失败,[2024-03-15 14:25:10] INFO 服务器启动,[2024-03-15 14:32:05] WARNING 内存使用率85%,[2024-03-15 14:25:10] DEBUG 加载配置文件,[2024-03-15 14:28:45] INFO 用户登录成功,]defextract_timestamp(log_line):从日志行中提取时间戳returnlog_line[1:20]# 提取 [2024-03-15 14:30:22] 中的时间sorted_logssorted(logs,keyextract_timestamp)forloginsorted_logs:print(log)# 按时间正序排列# 对于同时间的日志按级别排序LEVEL_PRIORITY{DEBUG:0,INFO:1,WARNING:2,ERROR:3}defsort_key(log_line):timestampextract_timestamp(log_line)# 提取日志级别levellog_line[22:].split()[0]priorityLEVEL_PRIORITY.get(level,99)return(timestamp,priority)sorted_logssorted(logs,keysort_key)5.2 自然排序importre# 人类期望的排序自然排序file1, file2, ..., file10, file11# 而不是字典序file1, file10, file11, file2, ...defnatural_sort_key(s):自然排序的key函数# 将字符串分割为文本和数字的交替序列partsre.split(r(\d),s)# 将数字部分转为整数return[int(part)ifpart.isdigit()elsepart.lower()forpartinparts]files[file10.txt,file1.txt,file2.txt,file20.txt,file11.txt]print(sorted(files))# [file1.txt, file10.txt, file11.txt, file2.txt, file20.txt] ← 字典序print(sorted(files,keynatural_sort_key))# [file1.txt, file2.txt, file10.txt, file11.txt, file20.txt] ← 自然序六、总结sorted()的key参数是Python排序系统的精髓它让你能按任意规则排序——从简单的按长度排到复杂的多字段组合排序。核心要点sorted()返回新列表list.sort()原地排序key函数定义排序依据——返回什么就按什么排元组key实现多级排序——keylambda x: (x.a, -x.b)稳定性——两次sorted可实现复杂排序lambda key是最常用的排序方式✅记住key返回的不是元素本身而是用于比较的排序值。合理使用key你能排序任何数据结构。
延伸阅读

更多相关文章

2026/9/12 20:03:19

Python函数:reduce()函数累积计算全掌握

Python函数:reduce()函数累积计算全掌握一、开篇:从"逐个处理"到"累积计算" map()对序列中的每个元素应用同一个操作,filter()从序列中筛选出符合条件的元素。而reduce()的思路完全不同——它将序列中的元素两两聚合&…

2026/9/13 3:29:04

Airflow任务级补跑:精准可控的生产级数据修复实践

1. 项目概述:为什么“任务级补跑”比“DAG级补跑”更精准、更安全 在Airflow生产环境中,我见过太多团队把 catchupTrue 当成万能开关——DAG上线就开,调度一出问题就重启补跑,结果半夜收到告警:数据库连接池被打爆、…

2026/9/11 16:12:13

用思维赚钱

一、赚钱,和学历有关系,也没有关系,非必然 我的母亲,是个地地道道的农民,大约读过半年书,也就是小学一年级只读了约莫一个学期,那时家里穷、小孩子生得多,她在家里中孩子排行老二&am…

2026/9/13 23:18:21

遥感图像融合经典算法:IHS变换原理、实现与参数调优

简介:面向遥感图像处理初学者、课程设计及科研人员,这份MATLAB资源围绕HIS/IHS色彩空间变换,演示如何把多光谱与全色影像进行融合,以提升空间分辨率同时保留光谱信息。压缩包共7个文件,包括4幅TIFF格式测试影像&#x…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码