【问题标题】:Why is the sorted() function saying that it only takes one argument when passing 3 arguments?为什么 sorted() 函数在传递 3 个参数时说它只需要一个参数?
【发布时间】:2021-06-29 23:50:41
【问题描述】:

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

为什么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)

这给出的错误:

Traceback (most recent call last):
  File "...", line 4, in <module>
    sorted_array = sorted(iterable=array, key=operator.itemgetter(array[0][1]), reverse=True)
TypeError: sorted expected 1 argument, got 0

【问题讨论】:

  • 那么它说的是什么?一次不能有两个不同的错误消息。请显示确切的错误回溯。
  • @mkrieger1 两者都说:TypeError: sorted expected 1 argument, got 0.
  • 听起来不错@Ajay 我会研究 lambdas
  • @Ajay 为什么? operator 模块主要用于替换 lambdas 的使用与预定义的运算符函数...即而不是做lambda x,y: x + y 一个会只使用operator.add ...

标签: python


【解决方案1】:

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

TypeError: sorted expected 1 argument, got 0

一开始有点令人困惑。它的实际含义是:

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

the docs,签名是:

sorted(iterable, *, key=None, reverse=False)

根据this,函数签名中的* 意味着所有后续参数都必须命名。这并没有说明前面的论点。

在交互式 shell 中打印 help(sorted) 时,签名会更准确:

sorted(iterable, /, *, key=None, reverse=False)

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

sorted_array = sorted(array, key=..., reverse=True)

itemgetter作为key的正确使用请参考@Rivers' answer


我已在 official Python bug tracker 上报告了此文档问题。

【讨论】:

    【解决方案2】:

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

    有2个问题:

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

    1 - 可迭代:

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

    也许您认为iterable 是一个命名参数,但它不是。命名参数是 keyreverse(它们的名称后面有等号 (=))。

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

    sorted_array = sorted(array,...)
    

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

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

    itemgetter(0,1)
    

    但如果你真的想按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)
    

    输出:

    [[4, 5, 6], [1, 6, 3]]
    

    【讨论】:

    • 请注意,参数不会通过具有默认值来命名。拥有def foo(a): print(a) 并将其称为foo(a=5) 是完全可以的。请查看我的答案,了解这不起作用的真正原因
    • 非常感谢您指出这一点,我编辑了我的答案。
    猜你喜欢
    • 2019-10-19
    • 2017-01-02
    • 2019-03-11
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    相关资源
    最近更新 更多