Python TypeError: sort()不接受位置参数。

7
我尝试编写一个小类,并希望根据重量对项目进行排序。以下是提供的代码:
class Bird:

    def __init__(self, weight):
        # __weight for the private variable
        self.__weight = weight

    def weight(self):
        return self.__weight

    def __repr__(self):
        return "Bird, weight = " + str(self.__weight)


if __name__ == '__main__':

    # Create a list of Bird objects.
    birds = []
    birds.append(Bird(10))
    birds.append(Bird(5))
    birds.append(Bird(200))

    # Sort the birds by their weights.
    birds.sort(lambda b: b.weight())

    # Display sorted birds.
    for b in birds:
        print(b)

当我运行程序时,我得到了Python TypeError: sort() takes no positional arguments的错误堆栈。这是什么问题?

2
这个错误实际上是特定于Python3的。Python2会假设给定给sort的函数是一个cmp函数。上面的代码仍然会出错,因为你给它一个key函数。我发现这个问题是因为我的Python2脚本在Python3下运行时出错了。 - tobixen
3个回答

14

就是字面意思: sort 不接受任何位置参数,它只接受一个名为 key 的关键字参数:

birds.sort(key=lambda b: b.weight())

文档中:

sort(*, key=None, reverse=False)

此方法在原地对列表进行排序,仅使用项目之间的<比较。异常不会被抑制-如果任何比较操作失败,则整个排序操作将失败(并且列表可能处于部分修改状态)。

sort()接受两个参数,这些参数只能通过关键字传递(关键字参数):

key指定一个具有一个参数的函数,用于从每个列表元素中提取比较键(例如,key=str.lower)。 与列表中每个项对应的键会计算一次,然后用于整个排序过程。 None的默认值意味着直接排序列表项而不计算单独的键值。

[...]

签名中的*是位置参数和仅限关键字参数之间的分隔符;它作为初始“参数”的位置表示缺少位置参数。


4
这是有历史原因的。在早期的Python中,它需要一个cmp函数来进行比较。后来,加入了可以传递key函数而不是cmp函数的可能性。在Python3中,传递cmp函数的可能性被删除了。为了确保旧的Python2脚本(将cmp函数作为位置参数传递)不会出现更加难以理解的错误,sort不再接受位置参数。 - tobixen

6

查看list.sort文档,可以看到key是一个关键字参数。因此将该行代码

birds.sort(lambda b: b.weight())

改为

birds.sort(key=(lambda b: b.weight()))


3
键名不需要用括号包裹。使用key=lambda b: b.weight()即可。 - r.ook
@alec935 我不同意。只需看看chepner的答案,就会发现没有多余的括号,而且更易于阅读,实现的效果也是一样的。如果OP在sort之前有更多嵌套的代码,那么多少个闭合括号才算太多呢? - r.ook

3

sort() 只接受一个 key 参数和(可选的)reverse 参数。你给 sort() 提供了一个它无法接受的参数。只需在你的 lambda 前面添加 key= 即可。

错误信息是因为 key 参数只接受关键字参数,不接受位置参数。位置参数是指不跟随等号和默认值的名称。


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