Functional Programming with Python: Quick Reference with Examples

Functional Programming with Python: Quick Reference with Examples

Last updated:
Functional Programming with Python: Quick Reference with Examples
Source

Functional programming means, among other things, using higher order functions (functions that take functions as parameters) and avoiding creating mutable state (e.g. changing a variable's value) so as to make it easier to reason about programs, use the stack more effectively and reduce complexity in concurrent/parallel programs.

Most functional operations operate on lists

The news are that you can do in most languages. Here are a few things you can do in python to have a more functional program:

The lambda operator

The lambdaoperator in Python creates an anonymous, simplified function - a function without name.

This is useful because, in functional programming, you create a lot of functions that you only use once, so creating them in the usual way (using def, line breaks and return), while still possible, is too verbose for most cases.

# look, no def and no return()
f = lambda x,y: x + y

f(1,1) # equals 2
f(4,5) # equals 9

Suppose you want to create a simple function that adds two numbers. You can do it the usual way (using def) or using the lambda operator, as in the previous example.

map

The map function changes all elements in a list and returns the modified list

# just a simple list
numbers = [1,2,3,4,5]

# a function that multiplies a number by 2
doubles = map(lambda x: x*2, numbers) 
# doubles equals [2,4,6,8,10]

reduce

The reduce function applies an operation on every element and accumulates the results

# the same list as before
numbers = [1,2,3,4,5]

# add every number to an accumulator
sum = reduce(lambda acc, elem: acc + elem, numbers)
# sum equals 15 

The reducefunction is mostly used to obtain aggregate values from a list. For example, summing is one way to obtain a summary from a group of numbers.

The average is another such summary. Can you do it using reduce?

filter

The last element in our triptych is the filter function:

# a list of numbers
numbers = [1,2,3,4,5,6,7,8]

# a function that only returns True for odd numbers
odd_numbers = filter(lambda x: x % 2 == 1, numbers) # [1,3,5,7]

# and the opposite
even_numbers = filter(lambda x: x %2 == 0, numbers) # [2,4,6,8]

The filter function evaluates a predicate (a function that returns either true of false) for every element, and keeps those that evaluate to True

You can also

use a regular function (declared with def) instead of a lambda

If the functions you want to use in map, filter and reduce grow too large you can also use a regular function, for better readability:

# regular function
def powerof2(num):
    result = num ** 2

    return(result)

# use it the way you would a lambda
map(powerof2, [1, 2, 3, 4])
# returns [1, 4, 9, 16] 

Example use case

Suppose your boss has asked you to scan a document for URLs and produce a report of which domains appear how many times:

# assume functions load_document, is_url and extract_domain
# are defined elsewhere

# a document is a large string
document = load_document()

# use method split() to get a list of words instead
words = document.split()

# function is_url returns True if the argument is a well-formed
#   URL, False otherwise
urls = filter(is_url, words)

# function extract_domain extracts the domain (like "google.com")
#   part of a URL
domains = map(extract_domain, urls)

# let's build a dictionary, where keys are domains and values
#   are the number of times it appears in our document
# the result would be something like this: {'google.com': 10, 'cnn.com': 5}

# this function will be used next
def add_domain(a_dict, domain):
    if domain in a_dict.keys():
        a_dict[domain] += 1
    else:
        a_dict[domain] = 1

    # don't forget to return the modified dict
    return(a_dict) 

# you can also pass an initial value to function reduce
#  in this case, we'll use an empty dictionary
report = reduce( add_domain, domains, dict() )

print(report)
# mission accomplished

See also

  • Hadoop's MapReduce has been so named for a good reason (it uses the map and reduce functions throughout).

References

Dialogue & Discussion