Лямбды

Лямбды

Limera1n

Поговорим о лямбдах, функциях map и filter.

Давайте сразу перейдем к делу и на практике придем к тому, о чем нам надо поговорить.

Для начала давайте посмотрим методы трансформации одной последовательности в другую (сейчас все поймете :)):

Мы так же можем захотеть написать и другие функции преобразования, что не делает их бессмысленными. Тот факт, что они элементарные не делает эти функции бессмысленными, такие функции полезно было бы иметь. Однако количество различных всевозможных трансформаций безгранично, и просто нереально реализовать все эти функции так, что они покроют все эти случаи. Это одна из причин, почему функции могут принимать в качестве аргумента другие функции, и так же почему, собственно, так называемые лямбды существуют. Но все по порядку.

Посмотрим на функцию map

Что делает функция map? Эта функция к каждому элементу из списка, который ей передали, применяет функцию, которую передали ей в качестве первого аргумента. Мы передали функцию square и numbers. Что будет делать эта функция внутри? Она пойдет в цикле по numbers, возьмет первый элемент, вызовет функцию square и передаст его ей, запишет условно где то результат. И будет повторять это со следующими элементами внутри списка. В результате мы получим квадраты чисел, которые входят в список numbers. То есть функция map по сути отображает один список на другой список, применяя к первому списку поэлементно некую функцию преобразования, в данному случае это функция square.

Но мы видим в ответе непонятные числа. Это означает, что функция map возвращает итеральный объект по которому можно пройтись циклом, и если мы не присваиваем результат функции map, мы увидим просто некий адрес памяти этого объекта map. Поэтому мы видим его адрес в памяти. И другой важный факт здесь это то, что мы передаем функцию в качестве аргумента (обратите внимание на синтаксис), не прописывая круглы скобочки, то есть мы передаем просто имя функции. Это происходит по той причине, что мы передаем функцию в качестве аргумента, мы ее не вызываем. Вызвана она будет внутри функции map, и вызываться будет через вот такой синтаксис square(), а мы ее просто передаем на дальнейшие вызовы. То есть используя по сути ссылку на эту функцию, функция map будет вызывать эту функцию тогда, когда надо, то есть когда будет проходить циклом for по numbers. Такая необходимость вызова этой функции внутри функции map будет происходить только тогда, когда кто-то запросит результаты, то есть, например, пройдется циклом for по результаты возвращаемому из функции map, и только тогда на самом деле начнется итерирование по numbers. Это так называемое ленивое вычисление.

Показываю:

Если мы хотим получить список, выглядеть это будет так:

Получаем список с результатами.

Есть другая функция, называется filter

Одной из распространенных задач является фильтрация некой последовательности элементов, и с помощью этой фильтрации мы исключаем некоторые элементы из последовательности используя какое то условие. Для этого мы используем filter:

Мы видим такой же результат, как в случае с map. Но еще одно, в функцию обязательно передается метод, который возвращает True или False. Если при вызове элемента в результате будет False, например, 14 меньше, чем 18 и в список окончательный включен этот элемент не будет.

Теперь мы подходим к другому понятию - лямба выражение. Так же известное, как анонимные функции. Дело все в чем? Дело в том, что это довольно дорого определять отдельные функции все время, лишь для того, чтобы передать их в функцию map или filter. Дорого, в смысле, что это слишком много кода. Представим, что в программе нужна функция, которая будет задействована только один раз, зачем ее тогда объявлять, все равно она не будет переиспользована в другом месте. То есть это лишний труд, это просто хуже читается. Этого можно избежать с помощью лямбда выражений.

Так что такое лямбды?

Давайте трансформируем последний пример в лямбду:

Так же, мы можем такую лямбду встроить в вызов функции filter или map. Таким образом, если у нас есть простое выражение, и используется оно, так скажем, однажды, нет смысла реализовывать отдельную функцию, мы можем использовать для этого лямбда выражение.

Лямбда может работать и с двумя переменными:

Report Page