Я думаю, что все ответы здесь охватывают суть того, что лямбда-функция делает в контексте sorted () довольно хорошо, однако я все еще чувствую, что описание, которое приводит к интуитивному пониманию, отсутствует, поэтому вот мои двацентов.
Ради полноты излагаю очевидное заранее: sorted () возвращает список отсортированных элементов, и если мы хотим отсортировать определенным образом или если мы хотим отсортировать сложный списокэлементы (например, вложенные списки или список кортежей) мы можем вызвать ключевой аргумент.
Для меня интуитивное понимание ключевого аргумента, почему он должен вызываться, и использование лямбды в качестве (анонимная) вызываемая функция для достижения этой цели состоит из двух частей.
- Использование lamba в конечном итоге означает, что вам не нужно писать (определять) целую функцию, как та, что sblom предоставил пример.Лямбда-функции создаются, используются и немедленно уничтожаются, поэтому они не наполняют ваш код большим количеством кода, который будет использоваться только один раз.Это, насколько я понимаю, основная утилита лямбда-функции, и ее приложения для таких ролей широки.Его синтаксис является чисто условным, что по сути является природой программного синтаксиса в целом.Изучите синтаксис и покончите с этим.
Синтаксис лямбды следующий:
лямбда input_variable (s) : один вкусный лайнер
например
In [1]: f00 = lambda x: x/2
In [2]: f00(10)
Out[2]: 5.0
In [3]: (lambda x: x/2)(10)
Out[3]: 5.0
In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0
In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
Идея аргумента
key
заключается в том, что он должен принимать набор инструкций, которые по существу будут указывать функцию sorted () на те элементы списка, которые должны использоваться для сортировки.Когда он говорит
key=
, то на самом деле это означает: когда я перебираю список по одному элементу за раз (т.е. для e в списке), я собираюсь передать текущий элемент функции, которую я предоставляю в аргументе ключа.и использовать это, чтобы создать преобразованный список, который сообщит мне о порядке окончательного отсортированного списка.
Проверьте это:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Базовый пример:
sorted(mylist)
[2, 3, 3, 4, 6, 8,23] # все числа в порядке от малого к большому.
Пример 1:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)
[3, 3, 23, 6, 2, 4,8] # Имеет ли этот отсортированный результат интуитивный смысл для вас?
Заметьте, что моя лямбда-функция сказала сортировать, чтобы проверить, была ли (e) четной или нечетной перед сортировкой.
НО ЖДУ!Вы можете (или, возможно, должны) задаться вопросом о двух вещах - во-первых, почему мои шансы наступают раньше, чем мои события (поскольку мое значение ключа, похоже, говорит моей отсортированной функции назначать приоритеты для событий с помощью оператора mod в x%2==0
).Во-вторых, почему мои вечера вышли из строя?2 предшествует 6 верно?Анализируя этот результат, мы узнаем кое-что более глубокое о том, как работает аргумент «key» sorted (), особенно в сочетании с анонимной лямбда-функцией.
Во-первых, вы заметите, что, хотя шансы наступают раньше вечера, сами вечера не сортируются.Почему это?? Давайте прочитаем документы :
Функции клавиш Начиная с Python 2.4, в list.sort () и sorted () добавлен ключевой параметр для указанияфункция, вызываемая для каждого элемента списка перед сравнением.
Мы должны немного прочитать между строк здесь, но это говорит нам о том, что функция сортировки вызывается только один раз, и если мы указываем ключевой аргумент, то мы сортируем по значению, на которое указывает нам ключевая функция.
Так что же возвращает пример с модулем?Логическое значение: True == 1
, False == 0
.Так как же сортировка справляется с этим ключом?Он в основном преобразует исходный список в последовательность 1 и 0.
[3,6,3,2,4,8,23] становится [0,1,0,1,1,1,0]
Теперь мы кое-что получаем.Что вы получаете, когда сортируете преобразованный список?
[0,0,0,1,1,1,1]
Хорошо, теперь мы знаем, почему шансы наступают раньше вечера.Но следующий вопрос: почему 6 все еще стоят перед 2 в моем окончательном списке?Ну, это легко - это потому, что сортировка происходит только один раз!т.е. те 1 все еще представляют исходные значения списка, которые находятся в их исходных положениях относительно друг друга.Поскольку сортировка происходит только один раз, и мы не вызываем какую-либо функцию сортировки для упорядочения исходных четных значений от низкого к высокому, эти значения остаются в своем первоначальном порядке относительно друг друга.
Последний вопрос:тогда это: как я концептуально думаю о том, как порядок моих логических значений преобразуется обратно в исходные значения, когда я распечатываю окончательный отсортированный список?
Sorted () - это встроенный метод, который (забавный факт) использует гибридный алгоритм сортировки под названием Timsort , который объединяет аспекты сортировки слиянием и сортировки вставкой.Мне кажется ясным, что когда вы вызываете его, есть механизм, который хранит эти значения в памяти и связывает их с их логическим тождеством (маской), определяемым (...!) Лямбда-функцией.Порядок определяется их булевой идентичностью, рассчитанной по лямбда-функции, но имейте в виду, что эти подсписки (единиц и нулей) сами по себе не сортируются по их исходным значениям.Следовательно, окончательный список, хотя и организован по коэффициентам и событиям, не отсортирован по подспискам (в этом случае четные номера не соответствуют порядку).Тот факт, что шансы упорядочены, объясняется тем, что они уже были в порядке по совпадению в исходном списке.Вывод из всего этого заключается в том, что когда лямбда выполняет это преобразование, первоначальный порядок подсписков сохраняется.
Так как же все это связано с исходным вопросом и, что более важно, с нашей интуицией о том, как мы должны реализовать sorted () с ее ключевым аргументом и лямбда-выражением?
Эта лямбда-функция может бытьрассматривается как указатель, который указывает на значения, по которым мы должны отсортировать, является ли указатель отображением значения в его логическое значение, преобразованное лямбда-функцией, или если это конкретный элемент во вложенном списке, кортеже, dict и т. д.,снова определяется лямбда-функцией.
Давайте попробуем предсказать, что произойдет, когда я запущу следующий код:
mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])
Мой sorted
вызов явно говорит: "Пожалуйста, сортируйте этот список".Ключевой аргумент делает это немного более конкретным, говоря, что для каждого элемента (x) в mylist возвращают индекс 1 этого элемента, а затем сортируют все элементы исходного списка 'mylist' по отсортированномупорядок списка, вычисляемый лямбда-функцией.Поскольку у нас есть список кортежей, мы можем вернуть индексированный элемент из этого кортежа.Таким образом, мы получаем:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Запустите этот код, и вы увидите, что это заказ.Попробуйте проиндексировать список целых чисел, и вы обнаружите, что код ломается.
Это было длинное объяснение, но я надеюсь, что это поможет «разобраться» в вашей интуиции об использовании лямбда-функций в качестве ключевого аргумента.в отсортированном виде () и далее.