似乎Python内置函数
min()
调用
指定的按键功能,即使只剩下一项:
foo = ['2']
def key_func(value):
print("Key function called")
return int(value)
print(min(foo, key=key_func))
给出:
Key function called
2
同样的观察也适用于
max()
和 sorted()
。
为什么
len(iterable) == 1
没有快捷方式?
想象一下当 key_func
进行昂贵的计算时的情况
那就没有用了。
我阅读了 Python 文档,但没有找到对此行为的解释,但我认为一定有一个解释,因为众所周知,Python 核心开发团队在定义和证明语言和标准库的行为时非常严格。
您必须选择其中之一,不能同时拥有:
key
始终按照可迭代中项目的原始顺序被调用一次;key
。这两个约定中的一个优于另一个并不明显,调用
min
或 sorted
并关心第二个约定的程序员可以在自己的代码中添加一个规定来实现这一效果,并且当可迭代对象只有一项时,根本不调用 sorted
。
请注意,并非所有可迭代对象都是像
list
和 tuple
这样的序列;一些迭代不支持 len
,因此在调用 key
之前检查它们是否有一个或多个项目的唯一方法是获取第一个项目,尝试获取第二个项目,并且仅当 StopIteration
尝试获取第二个项目时未引发,然后对第一个项目调用 key
。
想象一下当 key_func 进行昂贵的计算但没有用处的情况。
这是可能的,但可能不是关键功能的绝大多数用例;在许多情况下,关键只是
operator.itemgetter(...)
或 lambda x: x[1].upper()
或类似的东西。如果 key_func 执行昂贵的计算,您可能不想使用 key=key_func
,它会在工作完成后立即丢弃结果;您可能希望保留计算结果,以避免下次需要时重新计算。
当 key_func 进行昂贵的计算时,您提出的优化很好,但用户可以通过在调用
sorted
或 min
之前检查项目数量来显式完成;当 key_func 不进行昂贵的计算时(这可能是大多数情况),您提出的优化将比仅无条件调用 key 函数更昂贵。