Skip to main content

Lambda Expressions, Map, and Filter

· 7 min read
Shaurya Singhal

Source: View original notebook on GitHub

Category: Python / 1 Learn Python

Lambda Expressions, Map, and Filter

Now its time to quickly learn about two built in functions, filter and map. Once we learn about how these operate, we can learn about the lambda expression, which will come in handy when you begin to develop your skills further!

map function

The map function allows you to "map" a function to an iterable object. That is to say you can quickly call the same function to every item in an iterable, such as a list. For example:

map() is a built-in Python function that takes in two or more arguments: a function and one or more iterables, in the form:

map(function, iterable, ...)

map() returns an iterator - that is, map() returns a special object that yields one result at a time as needed.

def square(num):
return num**2
my_nums = [1,2,3,4,5]
m = map(square,my_nums)
# To get the results, either iterate through map() 
# or just cast to a list
list(map(square,my_nums))

Output:

[1, 4, 9, 16, 25]
next(m)

Output:

1
next(m)

Output:

4

The functions can also be more complex

def splicer(mystring):
if len(mystring) % 2 == 0:
return 'even'
else:
return mystring[0]
mynames = ['John','Cindy','Sarah','Kelly','Mike']
list(map(splicer,mynames))

Output:

['even', 'C', 'S', 'K', 'even']
def mul(x,y):
return x*y

can be written as
lambda x,y:x*y # i.e. no brackets no return ,no function name
# important we can pass two sequences as well
l1=[1,2,3]
l2 =[4,5,6]
l3 = [1,4,8]
l = list(map(lambda x,y:x*y , l1,l2)) # x will take values from l1 and y form l2
ldash = list(map(lambda x,y,z:x*y*z , l1,l2,l3))
print(l)
print(ldash)

Output:

[4, 10, 18]
[4, 40, 144]

filter function

The filter function returns an iterator yielding those items of iterable for which function(item) is true. Meaning you need to filter by a function that returns either True or False. Then passing that into filter (along with your iterable) and you will get back only the results that would return True when passed to the function.

The function filter(function, list) offers a convenient way to filter out all the elements of an iterable, for which the function returns True.

The function filter(function,list) needs a function as its first argument. The function needs to return a Boolean value (either True or False). This function will be applied to every element of the iterable. Only if the function returns True will the element of the iterable be included in the result.

Like map(), filter() returns an iterator - that is, filter yields one result at a time as needed.

def check_even(num):
return num % 2 == 0
nums = [0,1,2,3,4,5,6,7,8,9,10]
filter(check_even,nums)

Output:

<filter at 0x205baed4710>
list(filter(check_even,nums))

Output:

[0, 2, 4, 6, 8, 10]

lambda expression

One of Pythons most useful (and for beginners, confusing) tools is the lambda expression. lambda expressions allow us to create "anonymous" functions. This basically means we can quickly make ad-hoc functions without needing to properly define a function using def.

Function objects returned by running lambda expressions work exactly the same as those created and assigned by defs. There is key difference that makes lambda useful in specialized roles:

lambda's body is a single expression, not a block of statements.

  • The lambda's body is similar to what we would put in a def body's return statement. We simply type the result as an expression instead of explicitly returning it. Because it is limited to an expression, a lambda is less general that a def. We can only squeeze design, to limit program nesting. lambda is designed for coding simple functions, and def handles the larger tasks.

Lets slowly break down a lambda expression by deconstructing a function:

def square(num):
result = num**2
return result
square(2)

Output:

4

We could simplify it:

def square(num):
return num**2
square(2)

Output:

4

We could actually even write this all on one line.

def square(num): return num**2
square(2)

Output:

4

This is the form a function that a lambda expression intends to replicate. A lambda expression can then be written as:

lambda num: num ** 2

Output:

<function __main__.<lambda>>
# You wouldn't usually assign a name to a lambda expression, this is just for demonstration!
square = lambda num: num **2
square(2)

Output:

4

So why would use this? Many function calls need a function passed in, such as map and filter. Often you only need to use the function you are passing in once, so instead of formally defining it, you just use the lambda expression. Let's repeat some of the examples from above with a lambda expression

list(map(lambda num: num ** 2, my_nums))

Output:

[1, 4, 9, 16, 25]
list(filter(lambda n: n % 2 == 0,nums))

Output:

[0, 2, 4, 6, 8, 10]

Here are a few more examples, keep in mind the more complex a function is, the harder it is to translate into a lambda expression, meaning sometimes its just easier (and often the only way) to create the def keyword function.

Lambda expression for grabbing the first character of a string:

lambda s: s[0]

Output:

<function __main__.<lambda>>

Lambda expression for reversing a string:

lambda s: s[::-1]

Output:

<function __main__.<lambda>>

You can even pass in multiple arguments into a lambda expression. Again, keep in mind that not every function can be translated into a lambda expression.

lambda x,y : x + y

Output:

<function __main__.<lambda>>

You will find yourself using lambda expressions often with certain non-built-in libraries, for example the pandas library for data analysis works very well with lambda expressions.

reduce() in functools module

The function reduce(function, sequence) continually applies the function to the sequence. It then returns a single value.

If seq = [ s1, s2, s3, ... , sn ], calling reduce(function, sequence) works like this:

  • At first the first two elements of seq will be applied to function, i.e. func(s1,s2)
  • The list on which reduce() works looks now like this: [ function(s1, s2), s3, ... , sn ]
  • In the next step the function will be applied on the previous result and the third element of the list, i.e. function(function(s1, s2),s3)
  • The list looks like this now: [ function(function(s1, s2),s3), ... , sn ]
  • It continues like this until just one element is left and return this element as the result of reduce()

Let's see an example:

from functools import reduce

lst =[47,11,42,13]
reduce(lambda x,y: x+y,lst)

Output:

113

Lets look at a diagram to get a better understanding of what is going on here:

from IPython.display import Image # explore more on Ipython.display Module yourself to add youtubevideos, pdf etc.
Image('images/reduce_ex.png')

Output

Note how we keep reducing the sequence until a single final value is obtained. Lets see another example:

#Find the maximum of a sequence (This already exists as max())
max_find = lambda a,b: a if (a > b) else b
#Find max
reduce(max_find,lst)

Output:

47