Python TypeError: sort() takes no positional arguments

13,202

Solution 1

Exactly what it says: sort doesn't take any positional arguments. It takes a keyword-only argument named key:

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

From the documentation:

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

This method sorts the list in place, using only < comparisons between items. Exceptions are not suppressed - if any comparison operations fail, the entire sort operation will fail (and the list will likely be left in a partially modified state).

sort() accepts two arguments that can only be passed by keyword (keyword-only arguments):

key specifies a function of one argument that is used to extract a comparison key from each list element (for example, key=str.lower). The key corresponding to each item in the list is calculated once and then used for the entire sorting process. The default value of None means that list items are sorted directly without calculating a separate key value.

[...]

The * in the signature is the separator between positional parameters and keyword-only parameters; its position as the initial "argument" indicates the lack of positional parameters.

Solution 2

Looking at the documentation for list.sort, we can see that key is a keyword-only argument. So change the line

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

to

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

Solution 3

sort() takes a key argument and nothing else (well, it can take a reverse argument). You supplied sort() with an argument it cannot accept. Just add a key= before your lambda

The error message is because key takes keyword arguments, not positional arguments. A positional argument is a name that is not followed by an equal sign and default value.

Share:
13,202
Arefe
Author by

Arefe

Updated on June 26, 2022

Comments

  • Arefe
    Arefe almost 2 years

    I try to write a small class and want to sort the items based on the weight. The code is provided,

    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)
    

    When I run the program, I get the error stack of Python TypeError: sort() takes no positional arguments. Whats the issue here?

  • r.ook
    r.ook about 5 years
    You don't need the parentheses for the key though. just key=lambda b: b.weight() will suffice.
  • r.ook
    r.ook about 5 years
    @alec935 I beg to differ. Just take a look at chepner's answer. So much easier to read without the superfluous parentheses and it does the same thing. If OP has more code nested before the sort, how many closing parentheses is too much?
  • tobixen
    tobixen over 4 years
    There is a historic reason why it's like this. In early python a cmp-function was expected. The possibility to pass a key-function rather than a cmp-function was added at some point. The possibility to pass the cmp-function was removed in python3. To make sure old python2-scripts (passing a cmp-function as a positional argument) wouldn't break with an even more obscure error, sort does no longer accept the positional argument.