After migration to Python 3 from Python 2, *lambda *operator*, map() *and* filter()* functions are still part of core Python; only *reduce()* function had to go, and it was moved into the module *functools*.

This post introduces how to use *lambda, map,* *filter, and reduce *functions in Python 3 (for python 2.7 version, check the references below.)

Some people like it, others hate it and many are afraid of the lambda operator.

The lambda operator or lambda function *is a way to create small anonymous functions *(i.e., functions without a name). These functions are throw-away functions (i.e., they are just needed where they have been created).

*Lambda* functions are mainly used in combination with the functions *filter(), map() *and* reduce()*. The lambda feature was added to Python due to the demand from Lisp programmers.

The general syntax of a lambda function is quite simple:

**lambda argument_list: expression**

The argument list consists of *a comma separated list of arguments* and the expression is *an arithmetic expression using these arguments*. You can assign the function to a variable, so you can use it as a function.

The following example of a lambda function returns the sum of its two arguments:

>>> sum = lambda x, y **:** x + y
>>> sum(3,4)
7
>>>

The above example might look like a game for a mathematician — A formalization that turns a straight forward operation into an abstract formalization.

The above has the same effect by using the following conventional function definition:

>>> def sum(x,y):
... return x + y
...
>>> sum(3,4)
7
>>>

But, when you learn how to use the *map()* function, you will see the apparent advantages of this lambda operation.

The advantage of the lambda operator will be obvious when it is used in combination with the map() function.

*map()* is a function which takes two arguments:

*r = map(func, seq)*

The first argument *func* is the name of a function and the second a sequence (e.g. a list).

*seq*. *map()* applies the function *func* to all the elements of the sequence *seq*. *Before Python3, map() used to return a list*, where each element of the result list was the result of the function *func* applied on the corresponding element of the list or tuple “seq”. *In Python 3, map() returns an iterator.*

The following examples illustrate how* map() f*unction works:

>>> def fahrenheit(T):
... return ((float(9)/5)*T + 32)
...
# hit Return/Enter to exit to the >>> in your terminal.
>>> def celsius(T):
... return (float(5)/9)*(T-32)
...
# hit Return/Enter to exit to the >>> in your terminal.
>>> temperatures = (36.5, 37, 37.5, 38, 39)
>>> F = map(fahrenheit, temperatures)
>>> print(F)
<map object at 0x106d1c3c8>
>>> temperatures_in_Fahrenheit = list(F)
>>> print(temperatures_in_Fahrenheit)
[97.7, 98.60000000000001, 99.5, 100.4, 102.2]
>>> C = map(celsius, map(fahrenheit, temperatures))
>>> print(C)
<map object at 0x106d1c438>
>>> temperatures_in_Celsius = list(C)
>>> print(temperatures_in_Celsius)
[36.5, 37.00000000000001, 37.5, 38.00000000000001, 39.0]
>>>

In the example above we haven’t used *lambda*. When using lambda, we do not need to define and name the functions *fahrenheit()* and* celsius()*. You can see this in the following interactive session:

>>> C = [39.2, 36.5, 37.3, 38, 37.8]
>>> F = list(map(lambda x: (float(9)/5)*x + 32, C))
>>> print(F)
[102.56, 97.7, 99.14, 100.4, 100.03999999999999]
>>> C = list(map(lambda x: (float(5)/9)*(x-32), F))
>>> print(C)
[39.2, 36.5, 37.300000000000004, 38.00000000000001, 37.8]
>>>

*map()* can be applied to more than one list.

The lists don’t have to have the same length.

map() will apply its lambda function to the elements of the argument lists (i.e., it first applies to the elements with the 0th index, then to the elements with the 1st index until the n-th index is reached). See the following for an illustration example:

>>> a = [1, 2, 3, 4]
>>> b = [17, 12, 11, 10]
>>> c = [-1, -4, 5, 9]
>>> list(map(lambda x, y : x+y, a, b))
[18, 14, 14, 14]
>>> list(map(lambda x, y, z : x+y+z, a, b, c))
[17, 10, 19, 23]
>>> list(map(lambda x, y, z : 2.5*x + 2*y - z, a, b, c))
[37.5, 33.0, 24.5, 21.0]
>>>

We can see in the example above that the parameter x gets its values from the list a, while y gets its values from b, and z from list c.

**If one list has less elements than the others,*** map()* will stop when the shortest list has been completed the mapping:

>>> a = [1, 2, 3]
>>> b = [17, 12, 11, 10]
>>> c = [-1, -4, 5, 9]
>>>
>>> list(map(lambda x, y, z : 2.5*x + 2*y - z, a, b, c))
[37.5, 33.0, 24.5]
>>>

**filter(function, sequence)**

offers an elegant way to filter out all the elements of a sequence “sequence”, according to the return value of the function *function* (i.e., if the function returns True it will be kept in the returned iterator object of the filter function).

In other words: The function filter(f,l) needs a function *f* as its first argument. *f* has to return a *Boolean* value (i.e. either *True* or *False*). This function will be applied to every element of the list *l*. Only if *f* returns True will the element be produced by the iterator — which is the return value of *filter* function.

In the following example, we filter out first the odd and then the even elements of the sequence of the first 10 Fibonacci numbers:

>>> fibonacci = [0,1,1,2,3,5,8,13,21,34]
>>> odd_numbers = list(filter(lambda x: x % 2, fibonacci))
>>> print(odd_numbers)
[1, 1, 3, 5, 13, 21]
>>> even_numbers = list(filter(lambda x: x % 2 == 0, fibonacci))
>>> print(even_numbers)
[0, 2, 8]
>>>

- An example of combining
*filter() *and *lambda* functions

>>> filter(lambda x: x % 2 == 0, list(range(10,100)))
<filter object at 0x106d1c208>
#this will return all even number between 10 and 100.
>>> list(filter(lambda x: x % 2 == 0, list(range(10,100))))
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
>>>

*reduce()* had been dropped from the core of Python when migrating to Python 3. It was moved into the module `functools`

.

`reduce(func, seq)`

continually applies the function func() to the sequence seq. It returns a single value.

If seq = [ s_{1}, s_{2}, s_{3}, … , s_{n} ], calling reduce(func, seq) works like this:

- the first two elements of
*seq* will be applied to *func*, i.e. *func(s*_{1},s_{2}). The list on which* reduce()* applied to looks like this now: *[ func(s*_{1}, s_{2}), s_{3}, … , s_{n} ]
- Then,
*func* will be applied on the previous result and the third element of the list, that is, *func(func(s*_{1}, s_{2}),s_{3})

The list now looks like this:* [ func(func(s*_{1}, s_{2}),s_{3}), … , s_{n} ]
- repeat the steps until just one element is left and return this element as the result of
*reduce() *function.

If n is equal to 4 the previous explanation can be illustrated like this:

The following simple example illustrates how *reduce()* works.

>>> import functools
>>> functools.reduce(lambda x,y: x+y, [47,11,42,13])
113
>>>

The following diagram shows the intermediate steps of the calculation:

See below for some examples of using* reduce()* function.

#get maximum number from a list using reduce():
>>> from functools import reduce
>>> f = lambda a,b: a if (a > b) else b
>>> reduce(f, [47,11,42,102,13])
102
>>>

# Calculating the sum of the numbers from 1 to 100:
>>> from functools import reduce
>>> reduce(lambda x, y: x+y, range(1,101))
5050

It’s very straightforward to change the previous example to calculate the product (the factorial) from 1 to a number. We just need to change the “+” into “*”:

>>> reduce(lambda x, y: x*y, range(1,5))
24
>>>

**References:**