< Previous Page | Home Page | Next Page >
Functional programming decomposes a problem into a set of functions. Ideally, functions only take inputs and produce outputs, and don’t have any internal state that affects the output produced for a given input.
Functional programming tricks are essential in the realms of data science. Let's have a look at some of the most common elements of it.
Similar to def
, the lambda
function creates a function, which can be called later. However, instead of designing it to a name (as def
does) lambda
directly returns the funtion. Lambdas are thus also called anonymous functions.
Let's see how that difference looks in practice.
def func(x): # def directly assigns the function to the name "func"
return x ** 3
print(func(5))
test = lambda x: x ** 3 # lambda returns the result directly, we do not have to write "return"
test(5)
Ok, got it! Let's see how we can build a lambda function.
Syntax:
lambda [arg1, arg2, ..., argi] : [expression]
lambda
:
add = lambda x,y:x+y # the function takes two arguments and adds them together
add(1,2)
So far, we have always assigned our lambda function to a variable. In reality, however, this is bad practice (as you coud just create a normal def
function inestead).
Lambdas are useful when you need a throwaway function, i.e. you do not intend to re-use the respective operation.
Sorting is a common example of when lambda functions are useful.
Generally, we can sort an iterable via the sorted
method.
lst = [3,2,4,6,1]
sorted(lst)
Let's say now you wanted to sort a list of tuples lst = [("a", 33),("b",44),("c", 12)]
according to the second element within every tuple.
How do we tell our sorted method, what to sort by? Let's have a look at which parameters sorted
takes.
#run this to get further infos on the sorted method
sorted?
We can see that sorted takes a "custom key function to customize the sort order". Let's use a lambda function for this key function.
lst = [("a", 33),("b",44),("c", 12)]
print(lst)
lst = sorted(lst, key=lambda tuple_:tuple_[1]) # we tell the function that it should sort by every second element of each tuple
print(lst)
One further fundamental aspect of functional programming is the use of list comprehensions.
In the past we had the option to create and fill lists using for loops
:
inp = "hello"
outp = []
for i in inp:
outp.append(i)
print(outp)
List comprehensions accomplish the same but in a more concise manner.
[(expression) for (variable) in (iterable) (optional if)]
They consist of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The expressions can be anything, meaning you can put in all kinds of objects in lists.
The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
The list comprehension always returns a result list.
In case you are still uncertain on how you would go about building a list comprehension, make sure to read this helpful article on the topic.
# let's re-write the example above:
inp = "hello"
outp = [i for i in inp]
print(outp)
As we have seen before, we can also include if-statements as well as nested for-loops in our list comprehension.
# let's look at some examples
a = [x for y in range(5) for x in range(y)]
b = [x if x < 3 else "NO" for x in [1, 2, 3, 4, 5]]
c = [x for x in [y.lower() for y in "HELLO"]]
d = [number for number in range(0,100) if number % 2 == 0] # prints all even numbers from 0 to 100
print(a, "\n", b, "\n", c, "\n", d)
We can also apply the intuition behind list comprehensions on tuples or dictionaries. To do so, we just swap the []
for ()
or {}
respectively.
# create a dictionary the standart way
dct = {}
lst = [("Hello", "World"), ("Goodbye", "Life")]
for i, z in lst:
dct[i] = z
print(dct)
# let's do the same using list comprehensions
dct = {i: z for i, z in [("Hello", "World"), ("Goodbye", "Life")]}
print(dct)
The python map() function applies a given function to each item of an iterable (list, tuple etc.) and returns a list of the results. Often, map is used in combination with a lambda function.
The syntax of map() is:
map(function, iterable, ...)
lst = [1,2,3,4,5]
# let's multiply each element of the list with itself and return a list with the outputs
lst = list(map(lambda x: x*x, lst)) # lambda takes every element of the itearable "lst" as an input x and multiplies it with itself
print(lst)
Task: look at the following example and try guessing the output
x = ["abc", "cde", "f", "gh"]
print(list(map(list, x)))
The filter()
method constructs an iterator from elements of an iterable for which a function returns true.
In simple words, the filter() method filters the given iterable with the help of a function that tests each element in the iterable to be true or not.
The syntax of filter() method is:
filter(function, iterable)
The following example checks whether each number in range(10) can be divided by 2 (i.e. is even) and returns the even numbers in a list.
out = filter(lambda k: k%2 == 0, range(10))
print(list(out))
# again try guessing what the following code snippet accomplishes
x = ["abc", "cde", "f", "gh"]
print(list(filter(lambda k: len(k) > 2, x)))
The reduce() function is used to apply a particular function passed in its argument to all of the list elements mentioned in the sequence passed along.
The syntax looks like this:
reduce(function, iterable, initializer)
The function is applied to every element of the given iterable. If an initializer is provided (optional), it is used as the first value before using the values in the iterator.
Note: we need to import the module functools to be able to use reduce
from functools import reduce
lst = [0,1,2,3,4]
print(reduce(lambda lst,y: lst+y, lst, 10))
# start with 10 then add +0+1+2+3+4
#guess the output
x = ["abc", "cde", "f", "gh"]
print(reduce(lambda x,y: x+y, x, "HELLO"))
< Previous Page | Home Page | Next Page >