# 3.2. FuncProg Lambda¶

## 3.2.1. Rationale¶

• Lambda - Anonymous functions

• When function is used once

• When function is short

• You don't need to name it (hence it is anonymous)

lambda

Anonymous function

## 3.2.2. Syntax¶

lambda <arguments>: <expression>


Lambda Expressions:

>>> f = lambda x: x+1
>>> f = lambda x,y: x+y


Equivalent functions:

>>> def f(x):
...     return x+1

>>> def f(x,y):
...     return x+y


## 3.2.3. Convention¶

• Usually parameters are named x and y

• Use shortest code possible

• Do not assign lambda to variable

• Lambda is anonymous function and it should stay anonymous. Do not name it

• PEP 8 -- Style Guide for Python Code: "Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier". Lambda is anonymous function and it should stay anonymous. Do not name it.

• Usually there are no spaces in lambda expressions (to make code shorter)

>>> square = lambda x: x**2
>>> square(4)
16


Good:

>>> def square(x):
...     return x**2
...
>>> square(4)
16


PEP 8 -- Style Guide for Python Code: "Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier":

## 3.2.4. Noop¶

>>> noop = lambda: ...

>>> def request(on_error = lambda: ...):
...     ...


## 3.2.5. Lambda with Map¶

Increment:

>>> data = [1, 2, 3, 4]
>>>
>>> result = map(lambda x: x+1, data)
>>> list(result)
[2, 3, 4, 5]


## 3.2.6. Lambda with Filter¶

Even numbers:

>>> DATA = [1, 2, 3, 4]
>>>
>>> result = filter(lambda x: x%2==0, DATA)
>>> list(result)
[2, 4]


## 3.2.7. Performance¶

>>> %%timeit -r 1000 -n 10_000
... def increment(x):
...     return x + 1
... map(increment, range(0,100))
271 ns ± 30.6 ns per loop (mean ± std. dev. of 1000 runs, 10000 loops each)
>>>
>>>
>>> %%timeit -r 1000 -n 10_000
... map(lambda x: x+1, range(0,100))
262 ns ± 29 ns per loop (mean ± std. dev. of 1000 runs, 10000 loops each)

>>> %%timeit -r 1000 -n 1000
... def increment(x):
...     return x + 1
... list(map(increment, range(0,100)))
7.48 µs ± 608 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
>>>
>>>
>>> %%timeit -r 1000 -n 1000
... list(map(lambda x: x+1, range(0,100)))
7.36 µs ± 545 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)


## 3.2.8. Use Case - Square¶

>>> data = [1, 2, 3, 4]
>>>
>>> result = map(lambda x: x**2, data)
>>> list(result)
[1, 4, 9, 16]


## 3.2.9. Use Case - Translate¶

>>> PL = {'ą': 'a', 'ć': 'c', 'ę': 'e',
...       'ł': 'l', 'ń': 'n', 'ó': 'o',
...       'ś': 's', 'ż': 'z', 'ź': 'z'}
>>>
>>> text = 'zażółć gęślą jaźń'
>>>
>>>
>>> result = map(lambda x: PL.get(x,x), text)
>>> str.join('', result)
'zazolc gesla jazn'


## 3.2.10. Use Cases - Adults¶

>>> people = [
...     {'age': 21, 'name': 'Jan Twardowski'},
...     {'age': 25, 'name': 'Mark Watney'},
...     {'age': 18, 'name': 'Melissa Lewis'}]
>>>
>>>
>>> result = filter(lambda x: x['age'] >= 21, people)
>>> list(result)
[{'age': 21, 'name': 'Jan Twardowski'},
{'age': 25, 'name': 'Mark Watney'}]


## 3.2.11. Use Case - Astronaut¶

>>> people = [
...     {'is_astronaut': False, 'name': 'Jan Twardowski'},
...     {'is_astronaut': True, 'name': 'Mark Watney'},
...     {'is_astronaut': True, 'name': 'Melissa Lewis'}]
>>>
>>>
>>> result = filter(lambda x: x['is_astronaut'], people)
>>> list(result)
[{'is_astronaut': True, 'name': 'Mark Watney'},
{'is_astronaut': True, 'name': 'Melissa Lewis'}]

>>> astronauts = ['Mark Watney', 'Melissa Lewis']
>>>
>>> people = ['Jan Twardowski', 'Mark Watney',
...           'Melissa Lewis', 'Jose Jimenez']
>>>
>>>
>>> result = filter(lambda x: x in astronauts, people)
>>> list(result)
['Mark Watney', 'Melissa Lewis']


## 3.2.12. Assignments¶

"""
* Assignment: FuncProg Lambda Chain
* Required: yes
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
1. Inline functions odd() and cube() with lambda expressions
2. Run doctests - all must succeed

Polish:
1. Wciel (inline) kod odd() i cube() wykorzystując wyrażenia lambda
2. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* mean = sum(...) / len(...)
* type cast to list() before calculating mean to expand generator

Tests:
>>> import sys; sys.tracebacklimit = 0

>>> type(result) is float
True
>>> result
11502.0
"""

def odd(x):
return x % 2

def cube(x):
return x ** 3

# float: Inline lambda expressions
result = (x for x in range(1, 34) if x % 3 == 0)
result = filter(odd, result)
result = map(cube, result)
result = list(result)
result = sum(result) / len(result)