python 3 彻底移除了 sort() 和 sorted() 的 cmp 参数,因其调用频繁、性能差且语义不清;改用 key 参数可对每个元素只调用一次,提升性能与可读性。

为什么 sort() 和 sorted() 不再接受 cmp 参数
因为 Python 3 彻底移除了 cmp 参数,这不是 bug,也不是临时调整,而是语言设计层面的硬性变更。任何写成 lst.sort(cmp=...) 或 sorted(..., cmp=...) 的代码,在 Python 3 中都会直接报错:TypeError: 'cmp' is an invalid keyword argument for sort()。
key 比 cmp 快,而且更安全
核心区别在于调用次数和语义清晰度:
-
cmp函数在排序过程中会被反复调用——同一元素可能参与几十次两两比较,每次都要传两个参数、返回-1/0/1 -
key函数对每个元素只调用一次,提取一个“排序键”,后续所有比较都基于这个键值进行,开销固定且可预测 - 比如按字典的
'age'字段排序,key=lambda x: x['age']直接、无歧义;而cmp得写成lambda a,b: (a['age'] > b['age']) - (a['age'] ,易错且难读
什么情况下非得用 cmp_to_key()
只有当你手头的排序逻辑**无法单靠一个元素决定顺序**时,才需要 functools.cmp_to_key():
- 典型场景:LeetCode 179 题“拼接最大数”,判断
'ab'和'cd'谁该排前面,得看'abcd'还是'cdab'更大 - 旧 Python 2 代码迁移,或第三方库返回了现成的
cmp函数 - 必须显式返回
-1/0/1,不能是布尔值或任意正负数 - 正确写法是
sorted(data, key=cmp_to_key(my_cmp)),不是sorted(data, cmp_to_key(my_cmp))(后者会报错)
多条件排序别写 cmp,直接用元组 key
绝大多数“先按 A 升序、再按 B 降序”的需求,根本不需要 cmp:
- 写成
key=lambda x: (x.a, -x.b)就够了(数值降序加负号) - 字符串降序慎用
-x.name,应改用(x.a, x.b, x.name.lower())+reverse=True或拆成两步 -
None值要兜底,比如key=lambda x: (x.priority or -1, x.name) - 复杂逻辑建议拆成独立函数,而不是塞进 lambda 里
真正容易被忽略的是:哪怕你只改了一行 cmp= → key=cmp_to_key(...),如果原 cmp 函数没严格返回 -1/0/1,或者误把 cmp_to_key 当成普通函数调用,排序结果就可能静默出错——它不会报错,但顺序不对。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











