Reputation: 23
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
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
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