Как работает ключевой аргумент для сортировки?

Код 1:

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

Код 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)]

Почему в коде 1 есть () опущен в key=str.lower, и он сообщает об ошибке, если скобки включены, но в коде 2 в key=itemgetter(2)скобки сохранены?

2 ответа

Решение

key аргумент sorted ожидает функцию, которая sorted затем применяется к каждому элементу сортируемой вещи. Результат key(item) сравниваются друг с другом, а не каждый оригинал item, в процессе сортировки.

Вы можете представить, что это работает примерно так:

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

Как видите, скобки () добавлены в функцию key внутри sorted, применяя его к x а также y, которые являются предметами thing_to_sort,

В вашем первом примере str.lower это функция, которая применяется к каждому x а также y,

itemgetter немного отличается Это функция, которая возвращает другую функцию, и в вашем примере это та другая функция, которая применяется к x а также y,

Вы можете увидеть, как itemgetter работает в консоли:

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

Поначалу может быть немного сложно разобраться с функциями "высшего порядка" (которые принимают или возвращают другие функции), но они очень полезны для множества различных задач, поэтому стоит поэкспериментировать с ними, пока вы не почувствуете себя комфортно,

Ковыряюсь с консолью немногоstr.lower переходит к методу 'lower' из 'str' объектов и str.lower() это функция, как никогда str.lower() требует аргумента, поэтому правильно написано было бы str.lower("OH BOY") и он вернется oh boy ошибка в том, что вы не передали аргументы функции, но она ожидала.

Другие вопросы по тегам