sorted() 的 key 必须是可调用对象(callable),它会被 sorted() 调用,返回排序依据
是的,sorted()
的 key
参数必须传入一个可调用对象(callable),这个 callable 负责计算每个元素的“排序依据”。
📌 为什么 key
需要是一个 callable?
Python 的 sorted()
需要对列表中的每个元素调用 key
指定的函数,获取排序的“权重”。它的执行流程如下:
- 遍历列表中的每个元素。
- 调用
key
指定的函数,获取排序依据(排序权重)。 - 按照排序依据对列表排序。
✅ 示例 1:key 需要是一个 callable
❌ 错误示范
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78}
]
sorted(students, key=students[0]['score']) # ❌ 错误!
❌ 报错
TypeError: 'int' object is not callable
原因
students[0]['score']
是85
,它是一个整数,不是一个函数。sorted()
期望key
传入一个函数,而85
不是函数,导致报错。
✅ 正确的写法
方法 1:使用 lambda
sorted(students, key=lambda s: s['score'])
🔹 解释
lambda s: s['score']
是一个函数,它接收s
(即列表中的一个元素),返回s['score']
作为排序依据。
方法 2:使用 operator.itemgetter()
from operator import itemgetter
sorted(students, key=itemgetter('score'))
🔹 解释
itemgetter('score')
返回一个函数,它的作用和lambda s: s['score']
相同,但性能更优。
✅ 证明 key
需要是 callable
让我们用 print()
观察 key
的调用过程:
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 92},
{"name": "Charlie", "score": 78}
]
def key_function(s):
print(f"调用 key_function 处理: {s}")
return s['score']
sorted_students = sorted(students, key=key_function)
✅ 输出
调用 key_function 处理: {'name': 'Alice', 'score': 85}
调用 key_function 处理: {'name': 'Bob', 'score': 92}
调用 key_function 处理: {'name': 'Charlie', 'score': 78}
🔍 观察
sorted()
会对列表中的每个元素调用key_function()
,以获取排序依据。sorted()
只接受可调用对象作为key
,否则会报错。
🎯 结论
sorted()
的key
必须是可调用对象(callable),它会被sorted()
调用,返回排序依据。- 不能传入具体的值(如
students[0]['score']
),因为sorted()
期望一个可以调用的函数,而不是一个单独的数值。 - 推荐
lambda
或itemgetter()
,都能正确提供 callable。
📌 最后复习
❌ 错误
sorted(students, key=students[0]['score']) # ❌ key 不能是一个数值
✅ 正确
sorted(students, key=lambda s: s['score']) # ✅ key 是一个函数
sorted(students, key=itemgetter('score')) # ✅ 更高效的写法