Functional Programming in Python

Make anonymous functions like lambda a, b, c: a + b * c!

Functional Programming in Python

Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing state and mutable data. Python supports many functional programming concepts:

1. First-Class Functions

In Python, functions are first-class objects, meaning they can be:

# Assigned to variables
def greet(name):
    return f"Hello, {name}!"

say_hello = greet
print(say_hello("Alice"))  # "Hello, Alice!"

# Passed as arguments
def apply_function(func, value):
    return func(value)

def double(x):
    return x * 2

result = apply_function(double, 5)  # 10

2. Lambda Functions

Lambda functions are small anonymous functions:

# Lambda syntax
square = lambda x: x ** 2
print(square(5))  # 25

# Lambda with multiple arguments
add = lambda x, y: x + y
print(add(3, 4))  # 7

# Lambda in sorting
pairs = [(1, 'one'), (2, 'two'), (3, 'three')]
pairs.sort(key=lambda pair: pair[1])  # Sort by second element

3. Map, Filter, and Reduce

Higher-order functions for working with iterables:

# Map: Apply function to every item
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# Filter: Keep items that meet condition
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # [2, 4]

# Reduce: Accumulate values
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120 (1*2*3*4*5)

4. List Comprehensions and Generator Expressions

Concise ways to create lists and generators:

# List comprehension
squares = [x**2 for x in range(10)]

# Generator expression
squares_gen = (x**2 for x in range(10))

# Filtered comprehension
even_squares = [x**2 for x in range(10) if x % 2 == 0]

# Dictionary comprehension
square_dict = {x: x**2 for x in range(5)}

5. Pure Functions

Functions that always produce the same output for the same input:

# Pure function
def add_numbers(x, y):
    return x + y

# Impure function (depends on external state)
total = 0
def add_to_total(x):
    global total
    total += x
    return total

6. Decorators

Functions that modify other functions:

# Simple decorator
def uppercase_decorator(func):
    def wrapper():
        result = func()
        return result.upper()
    return wrapper

@uppercase_decorator
def greet():
    return "hello, world!"

print(greet())  # "HELLO, WORLD!"

# Decorator with arguments
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")  # Prints "Hello, Alice!" three times

7. Partial Functions

Creating new functions with some arguments fixed:

from functools import partial

def power(base, exponent):
    return base ** exponent

# Create a function for squaring
square = partial(power, exponent=2)
print(square(5))  # 25

# Create a function for cubing
cube = partial(power, exponent=3)
print(cube(5))  # 125

8. Global Variables

Without the global keyword, a variable inside a function is considered local to that function. If you try to assign a value to a global variable inside a function, Python will treat it as a local variable, which will lead to an error if the variable doesn’t exist locally.

The global keyword lets you explicitly modify global variables from within a function.

For example:

x = 10  # Global variable

def change_x():
    global x  # Declare that x is global
    x = 20  # Modify the global variable

change_x()
print(x)  # Output will be 20

In the example above, x is initially a global variable. The change_x() function uses the global keyword to modify x. After the function is called, the global x becomes 20.

Conclusion

Functional programming in Python involves treating computation as the evaluation of mathematical functions and avoiding changing state and mutable data. Python supports many functional programming concepts, including first-class functions, lambda functions, map, filter, reduce, list comprehensions, generator expressions, pure functions, decorators, and partial functions. Some of these concepts include assigning functions to variables, passing functions as arguments, using lambda functions for anonymous functions, applying functions to every item in an iterable, creating concise lists and generators, and creating new functions with some arguments fixed.