Kevin King
Kevin King

Reputation: 23

How does the key argument to sorted work?

Code 1:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
    ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

Code 2:

>>> student_tuples = [
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> from operator import itemgetter, attrgetter
>>>
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Why in code 1, is () omitted in key=str.lower, and it reports error if parentheses are included, but in code 2 in key=itemgetter(2), the parentheses are kept?

Upvotes: 2

Views: 405

Answers (2)

schesis
schesis

Reputation: 59118

The key argument to sorted expects a function, which sorted then applies to each item of the thing to be sorted. The results of key(item) are compared to each other, instead of each original item, during the sorting process.

You can imagine it working a bit like this:

def sorted(thing_to_sort, key):
    #
    # ... lots of complicated stuff ...
    #
            if key(x) < key(y):
                # do something
            else:
                # do something else
    #
    # ... lots more complicated stuff ...
    #
    return result

As you can see, the parentheses () are added to the function key inside sorted, applying it to x and y, which are items of thing_to_sort.

In your first example, str.lower is the function that gets applied to each x and y.

itemgetter is a bit different. It's a function which returns another function, and in your example, it's that other function which gets applied to x and y.

You can see how itemgetter works in the console:

>>> from operator import itemgetter
>>> item = ('john', 'A', 15)
>>> func = itemgetter(2)
>>> func(item)
15

It can be a little hard to get your head around "higher order" functions (ones which accept or return other functions) at first, but they're very useful for lots of different tasks, so it's worth experimenting with them until you feel comfortable.

Upvotes: 3

TheBestNightSky
TheBestNightSky

Reputation: 51

poking around with the console a bit str.lower reefers to the method 'lower' of 'str' objects and str.lower() is a function, how ever str.lower() requires an argument, so properly written it would be str.lower("OH BOY") and it would return oh boy the error is because you did not pass any arguments to the function but it was expecting one.

Upvotes: -1

Related Questions