Функциональное программирование
TODO: Определение функционального программирование и краткий ликбез
Функция высшего порядка — в программировании функция, принимающая в качестве аргументов другие функции или возвращающая другую функцию в качестве результата. Основная идея состоит в том, что функции имеют тот же статус, что и другие объекты данных. Использование функций высшего порядка приводит к абстрактным и компактным программам, принимая во внимание сложность производимых ими вычислений
Функции первого класса - это означает, что язык поддерживает передачу функций в качестве аргументов другим функциям, возврат их как результат других функций, присваивание их переменным или сохранение в структурах данных
Термины друг на друга похожи, но давайте внесем ясность таким способом:
- Функция высшего порядка - К таким функциям относится глобальная функция
map
, которая действительно получает другую функцию в качестве первого аргумента. - Функции первого класса - А этот термин мы косвенно осбуждали в разделе про функции, когда рассматривали работу оператора
def
и то что он в действительности создает экземпляр классаfunction
, а это говорит нам о том, что мы можем работать с функциями как с обычными объектами, допустим присваивать их в переменные.def foo():passfoo2 = foo() # В этой строчке я только что присвоил в переменную `foo2` функцию `foo`
map
/filter
/sorted
/reduce
Давайте мы с вами рассмотрим некоторые функции высшего порядка и попробуем самостоятельно их реализовать.
map
Функция map(function, iterable, ...) -> iterator
получает 2 или более аргументов:
function
- давайте будем называть ее "функция-изменятор"iterable
- итерируемый объект
Cама же функция map
крайне простая она принимает "изменятор" и какую-то последовательность, после применяет "изменятор" к каждому элементу последовательности. Возвращает она итератор
Собственная реализация(пример):
filter
filter(function, iterable) -> iterator
- функция похожа на map
, но она не изменяет значения в последовательности, а фильтрует их. Получает она:
function
- давайте будем называть ее "функция-фильтратор"iterable
- итерируемый объект
Функция так же как и map
вернет итератор, в ходе работы которого она будет передавать значения из последовательности в функцию "фильтратор" и проверять проходит ли значение проверку или нет.
reduce
Это тоже очень полезная функция высшего порядка, вот только она не находится в глобальном скоупе, а импортируется из модуля functools
.
Она весьма универсальна и может использоваться как для того чтобы что-то отфильтровать или изменить. Но каноничным ее назначением является собрать какую-то последовательность в один объект. Может быть пока еще не понятно, что я имею ввиду, но на примерах станет понятнее.
Пример
Представим, что у нас есть список котов, у каждого кота есть идентификационный номер, но мы хотим с вами сделать так чтобы мы могли получать котов по их id
без перебора списка, тогда нам массив следующего вида:
надо представить в виде:
после этого мы сможем с вами получать кота по его id
через CATS_INDEX[699]
за O(1)
. Получается, что вместо списка котов мы получим словарь, где ключем является id
кота, а значением ссылка на dict
sorted
Как можно понять из название функция сортирует значения, для того чтобы отсортировать значение нам надо описать. Давайте зададимся вопросом, а какой основной принцип сортировки?
Функция будет сравнивать между собой пары сортируемых объектов, но для того чтобы явно указать по какому значению будет происходиться сравнение нам понадобится функция key_extractor
.