Синтаксис после сортировки (key = lambda:...)

Я не совсем понимаю синтаксис аргумента sorted():

key=lambda variable: variable[0]

Не lambda произвольно? Почему variable указано дважды в том, что выглядит как dict?

Ответ 1

key - это функция, которая будет вызываться для преобразования элементов коллекции до их сравнения. Параметр, передаваемый в key, должен быть чем-то вызываемым.

Использование lambda создает анонимную функцию (которая является вызываемой). В случае sorted вызываемый только принимает один параметр. Python lambda довольно прост. Он может делать только и возвращать одну вещь действительно.

Синтаксисом lambda является слово lambda, за которым следует список имен параметров, а затем один блок кода. Список параметров и блок кода обозначаются двоеточием. Это похоже на другие конструкции в python, такие как while, for, if и так далее. Это все утверждения, которые обычно имеют блок кода. Lambda - это еще один пример инструкции с кодовым блоком.

Мы можем сравнить использование лямбда с функцией def для создания функции.

adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2

lambda просто дает нам способ сделать это, не присваивая имя. Это делает его отличным для использования в качестве параметра функции.

variable используется здесь дважды, потому что в левой части двоеточия это имя параметра, а с правой стороны оно используется в блоке кода для вычисления чего-то.

Ответ 2

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

Для полноты картины я напишу очевидное заранее: sorted() возвращает список отсортированных элементов, и если мы хотим отсортировать определенным образом или если мы хотим отсортировать сложный список элементов (например, вложенные списки или список кортежей) мы можем вызвать ключевой аргумент.

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

  1. В конечном счете, использование 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'
  1. Идея, лежащая в основе аргумента 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] # all numbers are in order from small to large.

Пример 1:

mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)

[3, 3, 23, 6, 2, 4, 8] # Does this sorted result make intuitive sense to you?

Обратите внимание, что моя лямбда-функция сказала sorted, чтобы проверить, была ли (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] becomes [0,1,0,1,1,1,0]

Теперь мы куда-то добираемся. Что вы получаете, когда сортируете преобразованный список?

[0,0,0,1,1,1,1]

Хорошо, теперь мы знаем, почему шансы наступают раньше вечера. Но следующий вопрос: почему 6 все еще стоят перед 2 в моем окончательном списке? Ну, это так просто - сортировка происходит только один раз! т.е. эти единицы все еще представляют исходные значения списка, которые находятся в своих исходных положениях относительно друг друга. Поскольку сортировка происходит только один раз, и мы не вызываем какую-либо функцию сортировки, чтобы упорядочить исходные четные значения от низкого к высокому, эти значения остаются в своем первоначальном порядке относительно друг друга.

Последний вопрос заключается в следующем: как я концептуально думаю о том, как порядок моих логических значений преобразуется обратно в исходные значения при печати окончательного отсортированного списка?

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)]

Запустите этот код, и вы обнаружите, что это заказ. Попробуйте проиндексировать список целых чисел, и вы обнаружите, что код ломается.

Это было многословное объяснение, но я надеюсь, что это поможет "разобраться" в вашей интуиции об использовании лямбда-функций в качестве ключевого аргумента в sorted() и выше.

Ответ 4

variable слева от : - имя параметра. Использование variable справа использует параметр.

Значит почти то же самое, что:

def some_method(variable):
  return variable[0]

Ответ 5

lambda - анонимная функция, а не произвольная функция. Принятый параметр будет переменной, с которой вы работаете, и столбцом, в котором вы его сортируете.

Ответ 6

Еще один пример использования функции sorted() с key = lambda. Давайте рассмотрим, у вас есть список кортежей. В каждом кортеже у вас есть марка, модель и вес автомобиля, и вы хотите отсортировать этот список кортежей по марке, модели или весу. Вы можете сделать это с помощью лямбды.

cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]

print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))

Результаты:

[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]

Ответ 8

Просто перефразируя, ключ (Необязательно. Функция, выполняемая для определения порядка. По умолчанию - Нет) в отсортированных функциях ожидает функцию, и вы используете лямбду.

Чтобы определить лямбду, вы указываете свойство объекта, которое хотите отсортировать, и встроенная отсортированная функция python автоматически позаботится об этом.

Если вы хотите отсортировать по нескольким свойствам, присвойте key = lambda x: (property1, property2).

Чтобы указать упорядочение, передайте reverse = true в качестве третьего аргумента (Необязательно. Логическое значение. False отсортирует по возрастанию, True отсортирует по убыванию. По умолчанию False) отсортированной функции.