Сортировки и лямбда-функции
Параметр key стандартной сортировки
У стандартной сортировки (метода sort списка, функции sorted) есть более универсальный способ задания порядка сортировки при помощи параметра key. Значение этого параметра некоторая функция, которая вызывается для каждого элемента, перед сравнением этих элементов: элементы списка сортируются, но сравниваются не значения элементов, а результат вызова переданной функции от этого элемента.
Например, пусть дан список строк, содержащих цифры, нужно упорядочить элементы списка, сравнивая их, как числа, а не как строки. Это можно сделать так:
В сложных случаях функцию нужно написать самостоятельно, например, пусть дан список чисел, который нужно упорядочить по последней цифре. Напишем функцию, которая возвращает последнюю цифру числа:
Лямбда-функции
Например, отсортировать список чисел по последней цифре можно при помощи следующей лямбда-функции:
Элементами списка являются кортежи из двух координат, можно обратиться к этим координатам по индексам [0] и [1].
Устойчивость сортировки
Вернёмся к примеру сортировки по последней цифре. В приведённом выше примере упорядоченный список будет таким:
Этот пример иллюстрирует свойство устойчивости сортировки: функция сортировки не переставлят элементы, если они равны друг другу. В данном случае функция упорядочивает числа по последней цифре, а при равной последней цифре сохраняется порядок следования элементов в исходном списке: 22, 12, 32.
Что делать, если нужно сделать сложную сортировку, учитывающую несколько критериев? Например, при равной последней цифре нужно упорядочить элементы в порядке возрастания самих чисел.
Первый способ решения: напишем функцию, которая будет возвращать кортеж из двух чисел: последней цифры и самого числа. Кортежи сравниваются в лексикографическом порядке, поэтому при равенстве остатка от деления будут сравниваться сами числа.
Второй способ: воспользуемся устойчивостью сортировки. Отстортируем список сначала по возрастанию чисел, а затем — по последней цифре. Тогда при равном значении последней цифры сохранится ранее полученный порядок.
То есть сортировку по \(k\) параметрам (если по первому параметру элементы равны, то сравнить по второму, если равны два параметра, то сравнить по третьему и т.д.) можно заменить на \(k\) последовательных сортировок, выполняющихся в обратном порядке (от наименее значимого параметра к наиболее значимому).
Функция operator.itemgetter
При сортировке кортежей частой задачей является сортировка по какому-то одному элементу кортежа. Например, если нужно отсортировать кортежи по элементу с индексом 1, то можно написать такую лямбда-функцию:
Использование лямбда-функции для сортировки списков в Python
Перевод статьи «How to sort with lambda in Python».
Операции сортировки применяются к спискам данных на любом языке программирования. В Python для хранения наборов данных используются кортеж, список и словарь. Доступ к значениям кортежа и списка осуществляется по индексу, а к значениям словаря — по ключам.
В Python есть множество встроенных функций для сортировки списка данных в порядке возрастания или убывания. Лямбда-функция – одна из них. С ее помощью мы можем определить порядок сортировки в зависимости от требований.
Давайте рассмотрим на простых примерах использование лямбда-функции для сортировки списка чисел, кортежей, словарей и вложенного списка.
Пример 1. Сортировка списка чисел в формате строковых данных
Напишем код для сортировки списка строковых данных, которые являются числами, с применением лямбда-функции.
Зададим список из 6 элементов. Лямбду будем использовать внутри функции sorted() для сортировки списка.
В качестве первого аргумента функции указывается переменная списка, лямбда устанавливается в качестве значения ключа, а третьим аргументом передается начальная позиция сортировки. При помощи print() выводим в консоль отсортированный список через пробел.
Запустив наш код, получим следующий результат.
Пример 2. Сортировка списка кортежей
Теперь давайте напишем программу для сортировки списка из трех кортежей, каждый из которых состоит из трех элементов.
Здесь мы используем три типа сортировки.
В первой сортирующей функции позиция сортировки устанавливается в 0. Таким образом мы отсортируем список по первым элементам кортежей.
Во второй сортирующей функции позиция сортировки – 1. Так мы отсортируем список по вторым элементам кортежей.
Чтобы отсортировать список по третьим элементам кортежей, установим позицию сортировки 2.
Запустим наш код и получим три списка кортежей, отсортированных по указанным позициям.
Пример 3. Сортировка списка, состоящего из других списков
Теперь давайте напишем код для сортировки вложенного списка с использованием нашей лямбда-функции.
В нашем случае у нас есть три внутренних списка. Первый из них имеет три элемента, второй – два, а третий состоит из четырех элементов. Количество итераций внутреннего цикла for будет зависеть от количества элементов в каждом внутреннем списке.
Функция sorted() вызывает лямбда-выражение внутри внутреннего цикла для сортировки вложенного списка.
В выводе мы получим список из трех отсортированных списков.
Пример 4. Сортировка списка словарей
Напишем код для сортировки списка, состоящего из словарей, с использованием лямбда-функции.
Каждый словарь внутри списка содержит три пары ключ-значение.
Запустим нашу программу и получим следующий результат.
Заключение
Мы рассмотрели использование лямбда-функции для сортировки различных списков в Python. Разобрали на простых примерах, как можно отсортировать четыре разных списка. Надеемся, это поможет вам понять цель использования лямбда-функции при сортировке.
Функциональное программирование на Python для самых маленьких — Часть 1 — Lambda Функция
Я решил написать эту серию статей, ибо считаю, что никто не должен сталкиваться с той стеной непонимания, с которой столкнулся когда-то я.
Ведь большинство статей написаны таки образом что, для того чтобы понять что-то в Функциональном Программировании (далее ФП), тебе надо уже знать многое в ФП. Эту статью я старался написать максимально просто — настолько понятно, чтобы её суть мог уловить мой племянник, школьник, который сейчас делает свои первые шаги в Python.
Небольшое введение
Для начала, давайте разберемся, что такое функциональное программирование, в чем его особенности, зачем оно было придумано, а также где и как его использовать. Стоп… А зачем? Об этом написаны тонны материалов, да и в этой статье судя по всему эта информация не особо нужна. Эта статья написана для того, чтобы читатели научились разбираться в коде, который написан в функциональном стиле. Но если вы все-таки хотите разобраться в истории Функционального Программирования и в том, как оно работает под капотом, то советую вам почитать о таких вещах, как
Чистая Функция — Функция которая является детерминированной и не обладает никакими побочными эффектами.
То есть чтобы функция являлась чистой она должна быть детерминированной — то есть каждый раз при одинаковом наборе аргументов выдавать одинаковый результат.
Пример детерминированной функции
И пример не детерминированной:
Каждый раз при смене дня недели (который не является аргументом функции) функция выдает разные результаты.
Самый очевидный пример не детерминированной функции это random:
Второе важное качество чистой функции это отсутствие побочных эффектов.
Функция sort_by_sort имеет побочные эффекты потому что изменяет исходный список элементов и выводит что то в консоль.
В отличии от предыдущего примера функция sort_by_sorted не меняет исходного массива и возвращает результат не выводя его в консоль самостоятельно.
Чистые функции хороши тем что:
Функции высшего порядка — в программировании функция, принимающая в качестве аргументов другие функции или возвращающая другую функцию в качестве результата.
С основами чуть чуть разобрались и теперь перейдем к следующему шагу.
Итак, начнем
Для начала надо понять следующее — что такое Функциональное Программирование вообще. Лично я знаю две самые часто упоминаемые парадигмы в повседневном программировании — это ООП и ФП.
Если упрощать совсем и объяснять на пальцах, то описать эти две парадигмы можно следующим образом:
Это относится и к ФП — взял какие-то данные, взял какую-то функцию, поигрался с ними и выдал что-то на выходе.
Не стану расписывать всё, иначе это будет оооочень долго. Цель данной статьи — помочь разобраться, а не объяснить, как и что работает, поэтому тут мы рассмотрим основные функции из ФП.
В большинстве своем ФП (как я его воспринимаю) — это просто упрощенное написание кода. Любой код, написанный в функциональном стиле, может быть довольно легко переписан в обычном стиле без потери качества, но более примитивно. Цель ФП заключается в том, чтобы писать код более простой, понятный и который легче поддерживать, а также который занимает меньше памяти, ну и куда же без этого — разумеется, главная вечная мораль программирования — DRY (Don’t Repeat Yourself — Не повторяйся).
Сейчас мы с вами разберем одну из основных функций, которая применяется в ФП — Lambda функцию.
В следующих статьях мы разберем такие функции как Map, Zip, Filter и Reduce.
Lambda функция
Lambda — это инструмент в python и других языках программирования для вызова анонимных функций. Многим это скорее всего ничего не скажет и никак не прояснит того, как она работает, поэтому я расскажу вам просто механизм работы lambda выражений.
Рассмотрим пример. Например, нам надо написать функцию которая бы считала площадь круга при известном радиусе.
Формула площади круга это
где
S — это площадь круга
pi — математическая константа равная 3.14 которую мы получим из стандартной библиотеки Math
r — радиус круга — единственная переменная которую мы будем передавать нашей функции
Теперь оформим это все в python:
Вроде бы неплохо, но это всё может выглядеть куда круче, если записывать это через lambda:
Чтобы было понятнее, анонимный вызов функции подразумевает то, что вы используете её, нигде не объявляя, как в примере выше.
Лямбда функция работает по следующему принципу
Рассмотрим пример с двумя входными аргументами. Например, нам надо посчитать объем конуса по следующей формуле:
Запишем это все в python:
А теперь как это будет выглядеть в lambda форме:
Количество переменных здесь никак не ограничено. Для примера посчитаем объем усеченного конуса, где у нас учитываются 3 разные переменные.
Объем усеченного конуса считается по формуле:
И вот, как это будет выглядеть в python классически:
А теперь покажем, как это будет выглядеть с lambda:
После того, как мы разобрались, как работает lambda функция, давайте разберем ещё кое-что интересное, что можно делать с помощью lambda функции, что может оказаться для вас весьма неожиданным — Сортировку.
Сортировать одномерные списки в python с помощью lambda довольно глупо — это будет выглядеть, как бряцание мускулами там, где оно совсем не нужно.
Ну серьезно допустим, у нас есть обычный список (не важно состоящий из строк или чисел) и нам надо его отсортировать — тут же проще всего использовать встроенную функцию sorted(). И в правду, давайте посмотрим на это.
В таких ситуациях, действительно, хватает обычного sorted() (ну или sort(), если вам нужно изменить текущий список на месте без создания нового, изменив исходный).
Но что, если нужно отсортировать список словарей по разным ключам? Тут может быть запись как в классическом стиле, так и в функциональном. Допустим, у нас есть список книг вселенной Песни Льда и Пламени с датами их публикаций и количеством страниц в них.
Как всегда, начнем с классической записи.
А теперь перепишем это все через lambda функцию:
Таким образом, lambda функция хорошо подходит для сортировки многомерных списков по разным параметрам.
Если вы повторите весь этот код самостоятельно, написав его сами, то я уверен, что с этого момента вы сможете сказать, что отныне вы понимаете, как работают lambda выражения, и сможете применять их в работе.
Но где же тут та самая экономия места, времени и памяти? Экономится максимум пара строк.
И вот тут мы подходим к реально интересным вещам.
Которые разберем в следующей статье, где мы обсудим map функцию.
UPD: По многочисленным просьбам, расставил знаки препинания.
Все, что нужно знать о lambda-функциях в Python
В этой статье вы узнаете о том, что такое лямбда-функции в Python. На самом деле, если вы знаете, что такое функции и умеете с ними работать, то знаете и что такое лямбда.
Что такое лямбда в Python?
Прежде чем переходить как разбору понятия лямбда в Python, попробуем понять, чем является обычная функция Python на более глубоком уровне.
Для этого потребуется немного поменять направление мышление. Как вы знаете, все в Python является объектом.
Например, когда мы запускаем эту простейшую строку кода
А что происходит при определении вот такой функции:
Это же значит, что функции можно передать в качестве аргументов другим функциям или даже использовать их как тип возвращаемого значения.
Рассмотрим простой пример, где функция f передается другой функции.
Попробуйте разобраться самостоятельно с тем, что делает этот код, прежде чем читать дальше.
Итак, modify_list — это функция, которая принимает список L и функцию fn в качестве аргументов. Затем она перебирает список элемент за элементом и применяет функцию к каждому из них.
Но можно передать и любую другую, которая изменит оригинальный список другим способом. Это очень мощный инструмент.
Теперь, когда с основами разобрались, стоит перейти к лямбда. Лямбда в Python — это просто еще один способ определения функции. Вот базовый синтаксис лямбда-функции в Python:
Лямбда принимает любое количество аргументов (или ни одного), но состоит из одного выражения. Возвращаемое значение — значение, которому присвоена функция. Например, если нужно определить функцию f из примера выше, то это можно сделать вот так:
Но возникает вопрос: а зачем нужны лямбда-функции, если их можно объявлять традиционным образом? Но на самом деле, они полезны лишь в том случае, когда нужна одноразовая функция. Такие функции еще называют анонимными. И, как вы увидите дальше, есть масса ситуаций, где они оказываются нужны.
Лямбда с несколькими аргументами
Определить лямбда-функцию с одним аргументом не составляет труда.
А если их должно быть несколько, то достаточно лишь разделить значения запятыми. Предположим, что нужна функция, которая берет два числовых аргумента и возвращает их произведение.
Отлично! А как насчет лямбда-функции без аргументов?
Лямбда-функция без аргументов
Несколько лямбда-функций
В определенный момент возникнет вопрос: а можно ли иметь лямбда-функцию из нескольких строк.
Ответ однозначен: нет.
Лямбда-функции в Python всегда принимают только одно выражение. Если же их несколько, то лучше создать обычную функцию.
Примеры лямбда-функций
Теперь рассмотрим самые распространенные примеры использования лямбда-функций.
Лямбда-функция и map
Распространенная операция со списками в Python — применение операции к каждому элементу.
map() — это встроенная функция Python, принимающая в качестве аргумента функцию и последовательность. Она работает так, что применяет переданную функцию к каждому элементу.
Так, вместо определения функции и передачи ее в map в качестве аргумента, можно просто использовать лямбда для быстрого определения ее прямо внутри. В этом есть смысл, если упомянутая функция больше не будет использоваться в коде.
Вот еще один пример.
Лямбда-функция и filter
filter() — это еще одна встроенная функция, которая фильтрует последовательность итерируемого объекта.
Другими словами, функция filter отфильтровывает некоторые элементы итерируемого объекта (например, списка) на основе какого-то критерия. Критерий определяется за счет передачи функции в качестве аргумента. Она же применяется к каждому элементу объекта.
С лямбда-функциями это все можно сделать максимально сжато. Код выше можно преобразовать в такой, написанный в одну строку.
И в этом сила лямбда-функций.
Лямбда-функция и сортировка списков
Теперь создадим экземпляры этого класса и добавим их в список.
Предположим, что мы хотим отсортировать его на основе поля age сотрудников. Вот что нужно сделать для этого:
Пара слов о выражениях и инструкциях
Как уже упоминалось, лямбда могут иметь только одно выражение (expression) в теле.
Обратите внимание, что речь идет не об инструкции (statement).
Выражение и инструкции — две разные вещи, в которых часто путаются. В программировании инструкцией является строка кода, выполняющая что-то, но не генерирующая значение.
Например, инструкция if или циклы for и while являются примерами инструкций. Заменить инструкцию на значение попросту невозможно.
А вот выражения — это значения. Запросто можно заменить все выражения в программе на значения, и программа продолжит работать корректно.
Тело лямбда-функции должно являться выражением, поскольку его значение будет тем, что она вернет. Обязательно запомните это для работы с лямбда-функциями в будущем.
Хватит использовать lambda выражения в Python
Тяжело проводить глубокое изучение классов Python, не затрагивая вопрос лямбда выражений. Я практически всегда получаю кучу вопросов о них. Люди часто замечают их в коде на StackOverflow, или в коде коллеги (который, к слову, также может быть кодом с StackOverflow).
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Мне задают много вопросов про lambda и я не решаюсь рекомендовать студентам лямбда-выражения в Python. У меня была неприязнь к лямбда-выражениям на протяжении многих лет, и за годы обучения Python, это ощущение только усиливалось.
В этой статье я хочу объяснить, как я вижу лямбда-выражения и почему я рекомендую студентам избегать их использования.
Лямбда-выражения в Python: кто они?
Лябмда-выражения — это особый синтаксис в Python, необходимый для создания анонимных функций. Я назову синтаксис лямбда как лямбда-выражение, а получаемую функцию — лямбда-функцию.
Лямбда-выражения в Python позволяют функции быть созданной и переданной (зачастую другой функции) в одной строчке кода.
Лямдба-выражения позволяют нам превратить следующий код:
Лямбда-выражения — это особый синтаксис для создания функций. Они могут иметь только один оператор и автоматически возвращают его результат.
Встроенные ограничения лямбда-выражений являются их визитной карточкой. Когда опытный программист Python видит лямбда-выражение, он знает, что оно работает с функцией, которая используется только в одном месте и выполняет одну единственную задачу.
Если вы когда-либо использовали анонимные функции в JavaScript до этого, вы можете трактовать лямбда-выражения в Python аналогичным образом, с тем исключением, что у них больше ограничений и их синтаксис заметно отличается от привычного синтаксиса функций.
Где они используются?
Как правило, lambda-выражения используются при вызове функций (или классов), которые принимают функцию в качестве аргумента.
Встроенная функция сортировки Python принимает функцию в качестве ключевого аргумента. Эта ключевая функция использует для вычисления сравнительного ключа при определении порядка сортировки элементов.
Таким образом, сортировка — отличный пример места, в котором используются лямбда-выражения:
Приведенный выше пример возвращает указанные цвета, которые сортируются без учета регистра.
Функция sorted — не единственная область применения лямбда-выражений, но встречается наиболее часто.
Преимущества и недостатки lambda
Мое представление о лямбда-выражениях можно описать как постоянное сравнение с использованием def для определения функций. Оба этих инструмента дают нам функции, но каждый из них имеет разные ограничения и используют разный синтаксис.
Лямбда-выражения отличаются от def по следующим признакам:
Тот факт, что lambda-выражения могут свободно передаваться является главным преимуществом. Автоматический возврат — тоже удобно, но его с трудом можно назвать весомым преимуществом, на мой взгляд.
Наличие единственной строки кода я не вижу ни как преимуществом, ни как недостатком. Тот факт, что лямбда функции не имеют docstring и не имеют наименований — может быть неудобно, а незнакомый синтаксис — стать проблемой для новичков в Python.
На мой взгляд, в целом — недостатки немного перевешивают преимущества лямбда-выражений, но что мне больше всего не нравится, это то, что их постоянно либо используют неправильно, либо используют слишком часто.
Lambda используется неправильно и слишком часто
Когда я вижу лямбда-выражения в незнакомом коде, я сразу настраиваюсь скептически. Когда они появляются, я понимаю, что если их убрать, читаемость кода только улучшится.
Иногда проблема может заключаться в том, что они используются неправильно. Под этим имеется ввиду то, что способ их использования далек от идеала и неуместен. В других случаях, лямбда-выражения используются слишком часто. Под этим подразумевается то, что их наличие приемлемо, но код вполне может быть написан иначе.
Давайте посмотрим на различные примеры того, когда лямбда-выражения используются неправильно, или слишком часто.
Неправильное использование: наименование лямбда-выражений
PEP8, являющийся официальным руководством Python, рекомендует писать код таким образом:
Указанный вверху оператор создает анонимную функцию и затем присваивает её переменной. Этот код игнорирует причину, по которой лямбда функции являются полезными:
лямбда функции могут быть переданы без необходимости в предварительном присваивании переменной.
Если вы хотите создать однострочную функцию и хранить ее в переменной, вам нужно использовать def вместо этого:
Это рекомендуется в PEP8, так как названные функции — это простой и понятный элемент. Также полезно давать функции правильное наименование, чтобы упростить лечение возможных багов. В отличие от функций, определенных при помощи def, функции лямбда никогда не имеют названий (название всегда будет ):
Если вы хотите создать функции и хранить ее в переменной, определите вашу функцию при помощи def. Это именно то, для чего он нужен. Неважно, если ваша функция длиной в одну строку кода, или вы определяете функцию внутри другой функции, def отлично работает в таких случаях.
Неправильное использование: ненужные вызовы функций
Я часто сталкиваюсь с тем, что лямбда-выражения используются как обертка вокруг функции, которая и так подходит для решения задачи.
Рассмотрим следующий код в качестве примера:
Скорее всего, человек, написавший этот код, прочитал о том, что лямбда-выражения используются для того, чтобы создать функцию, которая может передаваться. Однако он не учел то, что картина несколько шире: все функции в Python (не только функции лямбда) могут передаваться.
Поскольку abs (который возвращает абсолютное значение числа) является функцией, а все функции могут передаваться, мы можем написать вышеупомянутый код следующим образом:
Теперь этот пример может казаться слегка надуманным, но и чрезмерное использование лямбда-выражений можно воспринимать аналогично. Вот еще один пример:
Так как мы принимает абсолютно те же аргументы, которые передаем в min, нам не нужен дополнительный вызов функции. Мы можем просто передать функцию min нашему ключу:
Вам не нужна лямбда функция, если у вас уже есть другая функция, выполняющая то, что вам нужно.
Злоупотребление: простые, но нетривиальные функции
Часто встречается использование лямбда-выражений для создания функции, которая возвращает несколько значений в кортеж python:
Используемая функция-ключ в этом примере помогает нам распределить цвета по длине в соответствии с их названиями.
Этот код аналогичен приведенному выше, но я нахожу его более читаемым:
Этот код немного нуднее, но на мой взгляд, наименование нашей функции делает более понятным по каким признакам мы собираемся проводить сортировку. Мы не просто сортируем по длине и не по цвету: мы сортируем по обеим признакам.
Если функция важная — желательно дать ей название. Вы можете не согласиться и сказать, что большинство функций, которые мы используем в лямбда-выражении настолько тривиальны, что их даже не нужно называть, и есть небольшие недостатки в наименовании функций, но на мой взгляд, это делает код более читаемым в конечном счете.
Обычные функции часто делают код более читаемым, так же, как использование распаковки кортежей вместо использования произвольных индексированных запросов также делает код более читаемым.
Злоупотребление: когда множество строк должны помочь
Иногда такой аспект, как «просто одна строка» в лямбда-выражениях заставляет нас делать код более запутанным. Например, вот так:
Мы старательно прописываем индексный поиск, чтобы сортировать точки по их цветам. Если мы используем обычную функцию, мы сможем применить распаковку кортежей, чтобы сделать этот код более читаемым:
Распаковка кортежей может улучшить читаемость, используя детально прописанный индексный поиск. Использование лямбда-выражений нередко означает пожертвовать определенными языковыми возможностями Python, особенно теми, которые требуют несколько строк кода (таких, как дополнительный оператор присваивания).
Злоупотребление: лямбда с map и filter
Функции Python map и filter практически всегда идут рука об руку с лямбда-выражениями. В StackOverflow обычным делом считается ответом на вопрос «что такое лямбда?» следующий код:
Такие примеры кажутся мне слегка озадачивающими, так как я практически никогда не использую map и filter у себя в коде.
Функции Python map и filter используются для создания цикла над итерацией и создания новой итерации, которая либо слегка меняет каждый элемент, или фильтрует итерацию только по отношению к тем элементам, которые соответствуют определенным условиям.
Мы можем выполнить обе эти задачи при помощи списка или выражений генератора:
Лично я предпочитаю видеть указанные выражения генератора написанные над несколькими строками кода, но даже эти однострочные выражения генератора читаются легче, чем вызовы filter и map.
Общие операции отображения и фильтрации полезны, но нам в действительности не нужно фильтровать и отображать сами функции. Выражения генератора являются особым синтаксисом, который существует для задач, связанных с отображением и фильтрацией. Так что мой совет — использовать выражения генератора вместо функций map и filter.
Неправильное использование: иногда вам даже не нужно передавать функцию
Что на счет тех случаев, где вам нужно передать куда-нибудь функцию, которая выполняет одну единственную операцию?
Новички, которые только осваивают функциональное программирование иногда пишут код следующим образом:
Этот код вносит числа в список. Но есть лучший способ сделать это:
Встроенная функция sum в Python была создана именно для этой задачи.
Функция sum, наряду с рядом других специализированных инструментов Python, легко упустить из виду. Но я бы посоветовал вам найти более точечные инструменты при необходимости, так как они также хорошо сказываются на читаемости кода.
Вместо передачи функций другим функциям, поищите более специализированный способ решить свою проблему.
Злоупотребление: использование лямбды для очень простых операций
Скажем, вместо того, чтобы сложить числа, мы их умножаем:
Это лямбда-выражение необходимо, так как мы не можем передавать оператор * также, как если бы он был функцией. Если есть функция, являющаяся эквивалентом *, мы можем передать ее функции reduce вместо этого.
Стандартная библиотека Python также имеет целый модуль, созданный для того, чтобы решить эту проблему:
Модуль операторов в Python существует, чтобы упростить использование функций для различных операторов. Если вы практикуете функциональное программирование, операционный модуль Python может послужить вам другом.
В дополнение к предоставлению функций, соответствующих ряду операторов Python, модуль operator предоставляет несколько функций более высокого уровня для доступа к элементам и атрибута методов вызова.
Есть itemgetter, который помогает получить доступ к индексам списка (или последовательности) ключей словаря:
Также есть attrgetter для получения доступа к атрибутам объекта:
И methodcaller для вызова методов объекта:
Я постоянно отмечаю, что использование функций в модуле operator делает код чище, чем если бы я использовал аналогичные лямбда-выражения.
Злоупотребление: когда использование функций высокого порядка только мешает
Функция, которая принимает функцию в качестве аргумента называется функцией высокого порядка. Функции высокого порядка — это такой тип функций, которым мы обычно передаем наши функции лямбда.
Использование функций высокого порядка — обычное дело при освоении функционального программирования. Функциональное программирование — не единственный способ использовать Python: этот язык с несколькими парадигмами, так что мы можем совмещать и сопоставлять дисциплины программирования, чтобы сделать код более читаемым.
Второй код длиннее, но ребята без опыта в функциональном программировании могут найти его более простым для понимания.
Любой, кто прошел те или иные курсы Python, вполне может понять, что делает функция multiply_all, в то время как комбинация reduce/lambda будет, скорее всего, чем-то более загадочным для многих программистов Python.
В целом, передача одной функции другой, как правило, делает код более сложным, что вредит читаемости.
Стоит ли вообще использовать лямбда-выражения?
Я нахожу использование лямбда-выражений несколько проблематичным, и вот почему:
В то время как оператор def зачастую более понятен, в Python также имеется ряд возможностей, которые можно использовать для замены лямбда-выражений, включая особый синтаксис, встроенные функции (sum) и функции стандартной библиотеки (в модуле operators).
Скажу так: использование лямбда-выражений приемлемо только тогда, когда ваша ситуация соответствует всем следующим четырем критериям:
Если какое-либо из перечисленных утверждений не соответствует вашей ситуации, я бы порекомендовал написать новую функцию при помощи def (там, где это возможно), охватывающую функцию, которая уже существует в среде Python, и которая делает то, что вам нужно.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)






