为什么 sorted() 函数说传递 3 个参数时只需要一个参数?

Jak*_*est 2 python

我有一个简单的程序,它应该按键对数组进行排序。

为什么sorted()函数说它只需要 1 个参数,而我没有提供任何参数?

import operator

array = [[1, 6, 3], [4, 5, 6]]
sorted_array = sorted(iterable=array, key=operator.itemgetter(array[0][1]), reverse=True)
print(sorted_array)
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

import operator

array = [[1, 6, 3], [4, 5, 6]]
sorted_array = sorted(iterable=array, key=operator.itemgetter(array[0][1]), reverse=True)
print(sorted_array)
Run Code Online (Sandbox Code Playgroud)

Tom*_*koo 6

你的困惑是有道理的。错误:

TypeError: sorted expected 1 argument, got 0
Run Code Online (Sandbox Code Playgroud)

开始有点混乱。它的实际意思是:

排序预期 1 [位置]参数,得到 0

查看文档,签名是:

sorted expected 1 [positional] argument, got 0

根据this*函数签名中的裸表示必须命名以下所有参数。这并没有说明前面的论点。

help(sorted)在交互式 shell 中打印时提供更准确的签名:

sorted(iterable, *, key=None, reverse=False)
Run Code Online (Sandbox Code Playgroud)

根据这个,一个/在一个函数的签名意味着所有前面的参数必须是位置,即叫,现在解释了错误。您只需要将数组作为位置参数传递:

sorted_array = sorted(array, key=..., reverse=True)
Run Code Online (Sandbox Code Playgroud)

请参阅@Rivers 的答案以正确使用itemgetter作为密钥。


我已在官方 Python 错误跟踪器上报告了此文档问题。


Riv*_*ers 1

我会尽力给你一个清晰而详细的解释:

有2个问题:

  1. iterable不是命名参数
  2. itemgetter语法错误

1 - 可迭代:

这是函数的定义sorted(参见https://docs.python.org/3/library/functions.html#sorted): sorted(iterable, *, key=None, reverse=False)

也许您认为这iterable是一个命名参数,但事实并非如此。命名参数为keyand reverse(它们的名称后面有等号 (=))。

所以你不必写iterable=something。您只需提供一个可迭代的数据结构,因此在您的示例中,这是名为 的变量array

sorted_array = sorted(array,...)
Run Code Online (Sandbox Code Playgroud)

更新:请参阅@Tomerikoo 答案,了解在这种情况下不起作用的确切原因。

2 - Itemgetter: 你不能写itemgetter(array[0][1]),你只需要给出元素的索引,所以正如 @Ajay 在他的评论中写道,你可以这样写:

itemgetter(0,1)
Run Code Online (Sandbox Code Playgroud)

但如果你真的想按 排序array[0][1],你也应该使用@Ajay 写的 lambda 函数。

一体:

from operator import itemgetter

array = [[1,6,3], [4,5,6]]
sorted_array = sorted(array, key=itemgetter(0,1), reverse=True)
print(sorted_array)
Run Code Online (Sandbox Code Playgroud)

输出:

[[4, 5, 6], [1, 6, 3]]
Run Code Online (Sandbox Code Playgroud)