python 3 彻底移除 cmp 参数,因 key 方案性能更优、更简洁;需用 functools.cmp_to_key() 包装旧 cmp 逻辑,且必须传给 key 参数而非直接作参数。

Python 3 中 sort() 和 sorted() 确实彻底移除了 cmp 参数,任何带 cmp=... 的调用都会直接抛出 TypeError: 'cmp' is an invalid keyword argument for sort() ——这不是环境或版本问题,是语言层面的硬性变更。
为什么 cmp 被干掉?不是 bug,是性能和设计取舍
Python 2 的 cmp 函数每次比较都要传入两个元素、返回 -1/0/1,排序过程中同一元素可能被反复拉去比几十次;而 Python 3 的 key 函数只对每个元素调用一次,提取一个“排序键”,后续全靠键值比较。这对大数据量(比如上万条字典)意味着显著的开销下降。
更实际的一点:绝大多数排序逻辑其实只需要“从元素里取某个值”——比如按字典的 'age' 排、按字符串长度排、按文件修改时间排。这些用 key=lambda x: x['age'] 比写一个双参数比较函数更直白、更少出错。
修复方法:必须用 functools.cmp_to_key() 包装旧逻辑
如果你的逻辑**确实依赖两个元素之间的相对关系**(比如 LeetCode 179 题拼接最大数、自定义字符串忽略大小写的偏序),就不能硬套 key,得走 cmp_to_key 这条路:
- 必须从
functools导入:from functools import cmp_to_key -
cmp_to_key(...)返回的是一个可传给key参数的函数,不是直接丢给sort()的独立参数 - 旧式
cmp函数必须严格返回 -1 / 0 / 1,不能是布尔值或任意正负数 - 错误写法:
nums.sort(cmp=lambda a,b: a-b)或nums.sort(cmp_to_key(lambda a,b: a-b))—— 前者参数名错,后者位置错 - 正确写法:
nums.sort(key=cmp_to_key(lambda a, b: -1 if a > b else (1 if a
常见简写(整数升序):sorted(nums, key=cmp_to_key(lambda a, b: a - b)) —— 注意这只是巧合成立,因为 Python 比较时会把非零结果转为 True/False,但语义上不保证;严谨场景请显式返回 -1/0/1。
sort() 和 sorted() 的调用差异容易踩坑
两者都禁用 cmp,但行为不同,容易混淆:
-
list.sort()是就地修改,返回None;写成y = x.sort(key=...)后y是None,不是排好序的列表 -
sorted()总是返回新列表,原对象不变 - 如果用
cmp_to_key,key=...是唯一合法位置,不能省略关键字名 - 别试图在
sort()里传位置参数:nums.sort(cmp_to_key(...))会报TypeError: sort() takes no positional arguments
真正麻烦的不是语法转换,而是有些比较逻辑根本没法“单元素提取”——比如两个字符串谁该排前面,取决于它们拼起来是 'ab'+'cd' 大还是 'cd'+'ab' 小。这种场景下,cmp_to_key 是唯一能守住原有语义的出口,绕不开,也别想用 key 巧妙模拟。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











