Last active
July 26, 2017 00:17
-
-
Save Beastrock/634b7b0f2d308a88c0b4448c54edf724 to your computer and use it in GitHub Desktop.
Lambda functions. [For devman.org Q and A]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>Объясните на пальцах как они работают, перечитал кучу информации, но так и не могу понять глобально как они работают | |
# О ней.. | |
Для начала небольшое резюмэ. | |
****Lambda-функция**** - [анонимная функция](https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%BE%D0%BD%D0%B8%D0%BC%D0%BD%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F), простым неуглубляющимся в сорцы языком кэпа, функция не имеющая имени. | |
Наглядный пример отличия обычной функция от lambda можно увидеть, поигравшись с интерпретатором: | |
```python | |
>>> def normal_func(a): | |
... return a + 1 | |
>>> lambda_func = lambda a: a + 1 | |
``` | |
Вызывается она также как и обычная функция: | |
```python | |
>>> normal_func(1) | |
2 | |
>>> lambda_func(1) | |
2 | |
``` | |
По типу от обычной не отличается: | |
```python | |
>>> type(normal_func) | |
<type 'function'> | |
>>> type(lambda_func) | |
<type 'function'> | |
``` | |
Но, если мы вызовем magic-method `__name__`, который возвращает имя функции, то увидим разницу: | |
```python | |
>>> normal_func.__name__ | |
'normal_func' | |
>>> lambda_func.__name__ | |
'<lambda>' | |
``` | |
Имя у неё всё таки есть, как видите :) | |
А смысл конструкции простой, она ведет себя так: | |
```\ | |
def lambda(<аргумент(ы) на вход>): | |
# тело функции отсутствует | |
return <выражение, которая функция возвращает> | |
``` | |
А записывается, как мы помним, так: | |
``` | |
<lambda>(<аргумент(ы) на вход>): <выражение, которая функция возвращает> | |
``` | |
За `<выражение, которая функция возвращает>` может скрываться многое: | |
```python | |
>>> lambda x: int(x) #конвертация значения в int | |
>>> lambda x, y, z: x > y > z # cравнение интервала значений | |
>>> lambda x: x['key'] # взятие ключа из словаря | |
``` | |
# Зачем? | |
Вы бы стали объявлять переменную ради её одноразового использования? | |
Например в нашей `normal_func`: | |
```python | |
# Why? | |
def normal_func(a): | |
incremented_value = a + 1 | |
return incremented_value | |
# Ok | |
def normal_func(a): | |
return a + 1 | |
``` | |
Это нерационально. Вот по той же причине нерационально объявлять и функцию для одноразовой работёнки, когда можно обойтись короткой записью с lambda. Также небольшим плюсом lambda является её быстрота по сравнению с обычной функцией. | |
# Combination is the answer. Usage examples. | |
Как в Linux каждая команда делает качественно что-то одно, но при этом в множественной комбинации с другими командами образует сильный упрощающий жизнь инструмент, так и lambda функция синергирует с некоторыми [питоновскими built-in функциями]('https://docs.python.org/3.5/library/functions.html'). | |
Начнём с простого. | |
* `sorted()`, `sort()`, `max()` и `min()` - здесь lambda-функция выступает ключем, по которуму сортируется итерируемый объект(список, словарь и др.), берется максимальное или минимальное значение из него. Рассмотрим пример: | |
```python | |
>>> a = ['Съешь','ещё','этих','мягких','французких','булочек'] | |
>>> sorted(a, key=lambda x: len(x)) | |
['ещё', 'этих', 'Съешь', 'мягких', 'булочек', 'французких'] | |
``` | |
Список сортируется по тем значениям, которые получились в результате преобразования lambda-функцией. Такой финт может пригодиться в первых задачах. Как видите lambd'e можно смело передать на выход любую команду. Ссылка на [мини гайд по сортировке](https://wiki.python.org/moin/HowTo/Sorting). | |
<hr> | |
Три танкиста - три весёлых друга: `filter`, `map` и `lambda`. | |
* `map(function, iterable, ...)` - принимает итерируемый объект(список, словарь и др.) и также приНимает на вход функцию, которая затем, приМеняется ко всем элементам. Сама функция возвращает итератор по новому получившемуся списку. | |
```python | |
>>> simple_list = [1, 2, 3, 4, 5, 6, 7, 8] | |
>>> squares = map(lambda x: x**2, simple_list) | |
>>> list(squares) | |
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] | |
``` | |
* `filter(function, iterable)` - принимает на вход функцию, которая возвращает True/False и итерируемый объект(список, словарь и др.). Сама функция возвращает список со значениями, которые в результате применения lambda-функции возвратили True. | |
```python | |
>>> simple_list = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] | |
>>> | |
>>> list( filter((lambda x: x < 0), simple_list)) | |
[-5, -4, -3, -2, -1] | |
>>> | |
``` | |
<hr> | |
## Создание функций | |
Код ниже определяет функцию "make_incrementor", которая создаёт анонимную функцию и возвращает её. Возвращаемая функция и есть старая добрая normal_func из первого примера. Она прибавляет переданное ей значение к значению, которое уже было задано в аргументе "make_incrementor" при создании. | |
Можно насоздавать разных прибавляшек и присвоить им переменным. Это идея без lamda-функции выглядела бы не так лаконично. Другое дело нужно ли нам инкременторы эти или нет? =) Но как пример использования имеет место быть. | |
```python | |
>>> def make_incrementor (n): return lambda x: x + n | |
>>> | |
>>> f = make_incrementor(2) | |
>>> g = make_incrementor(6) | |
>>> | |
>>> f(42), g(42) | |
(44, 48) | |
>>> | |
>>> make_incrementor(22)(33) | |
55 | |
``` | |
<hr> | |
Много других примеров использования можно найти в этой [статье](http://www.bogotobogo.com/python/python_functions_lambda.php). Пруф быстродействия lamda и ещё одно множество примеров [здесь](http://www.bogotobogo.com/python/python_functions_lambda.php). | |
Также стоит помнить, что альтернативой filter- и map-функций являются list comprehensions, но это уже другая история. =) | |
```python | |
map(lambda x: x**2, range(5)) VS [x**2 for x in range(5)] | |
filter(lambda x: x.attribute == value, my_list) VS [x for x in my_list if x.attribute == value] | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment