为什么Python中的sorted()函数不接受位置参数?

7
a=[1,2,3,4]
def func(x):
   return x**x

b=sorted(a,func)

这行代码总是会报错->

TypeError: sorted 预期只有 1 个参数,但给出了 2 个

事实上,sorted 的语法为 sorted(iterable, key=None, reverse=False),其中 keyreverse 是可选的参数。根据这个规则,我传递的第二个参数必须与 key 一起使用。

并且当我定义自己的函数时

def func2(x,y=4,z=10):
    print(x,y,z)
func2(100,200)--->output-->>100 200 10

这里自动将200作为func2y参数传递。这是如何工作的呢?


在第一个例子中,你到底想做什么?按照项的平方进行排序吗?你期望什么输出? - bherbruck
4
从文档中可以看到:它有两个可选参数,必须作为关键字参数指定。 - Barmar
1
https://docs.python.org/3/library/functions.html#sorted - Barmar
1
b = sorted(a, key=func) 可以工作,但在这种情况下不会有太大作用。 - bherbruck
@TenaciousB 这只是一个例子,没有其他意思。为了让读者更清楚我的问题。 - Nirbhay Garg
2个回答

8
为什么在Python中,sorted()不接受位置参数?
因为在Python 2中,sorted()曾经接受位置参数,但第二个参数是比较函数,而不是现在的键函数。Python 3不再支持列表排序的比较函数,因此对sorted()进行了修改。将一个位置参数的含义静默更改被认为过于混淆,所以开发人员决定完全禁止位置参数(除了第一个要排序的可迭代对象),并要求一切都使用关键字参数。
这样做的目的是为了使在Python 2中未修改的代码调用sorted(sequence, function)会在Python 3中快速失败,而不是尝试将比较函数作为键函数调用,并用错误数量的参数调用它。这可以防止如果比较函数恰好接受可变数量的参数,或者如果序列为空,排序恰好“适用”于某些输入时可能引起的混乱。
同样地,sorted(sequence, cmp=function)由于cmp已被删除而提前失败。sorted(sequence, key=function)在Python 2和3中均按预期工作。

有没有类似PEP之类的东西涵盖了这个问题? - Phillyclause89
2
@Phillyclause89 我不知道有没有这样的文档。虽然有一些涵盖 Python 3 的 PEP(它们的编号以 3000 开头),但似乎曾经有很多决策是在邮件列表中进行的,而没有明确定义的程序。list.sortsorted 的更改似乎属于这种情况。 - user4815162342

8
除了@user4815162342的回答外,根据文档
sorted(iterable, *, key=None, reverse=False)

注意在iterablekey参数之间的*。 这是Python指定的语法,表示在*后面的每个参数必须被指定为关键字参数

因此,您的自定义函数应该定义如下以应用类似的实现:

def func2(x, *, y=4, z=10):
    print(x, y, z)

func2(100, 200)

类型错误:func2() 接受 1 个位置参数,但传递了 2 个。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接