> ## Documentation Index
> Fetch the complete documentation index at: https://fastapi2day.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Functional Programming in Python: map, filter & reduce

> Apply functional programming concepts in Python — declarative style, higher-order functions, and the map, filter, and reduce pipeline.

Python supports multiple programming paradigms, and **Functional Programming (FP)** is one of the most powerful. Rather than describing how to perform each computation step-by-step, FP lets you declare **what** transformation should happen and pass functions as values to drive that logic. Python's support for first-class functions, lambdas, and built-in tools like `map()`, `filter()`, and `reduce()` makes building clean, composable data pipelines natural and expressive.

## The Declarative Approach

**Imperative programming** focuses on *how* to solve a problem — you manage loops, indices, and mutable state. **Declarative programming** focuses on *what* you want — you express the logic of a computation without dictating its control flow.

### Side-by-Side Comparison

**Imperative (how to do it):**

```python theme={null}
numbers = [1, 2, 3, 4]
doubled = []
for num in numbers:
    doubled.append(num * 2)
print(doubled)   # [2, 4, 6, 8]
```

**Declarative (what to do):**

```python theme={null}
numbers = [1, 2, 3, 4]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)   # [2, 4, 6, 8]
```

Both produce the same result, but the declarative version is shorter, more expressive, and has no explicit loop or intermediate list to manage.

## Higher-Order Functions

A **Higher-Order Function** either accepts a function as an argument, returns a function as its result, or both.

### Passing Functions as Arguments

```python theme={null}
def process_numbers(numbers, operation):
    return [operation(num) for num in numbers]

def square(x):
    return x * x

def cube(x):
    return x ** 3

nums = [1, 2, 3, 4, 5]
print(process_numbers(nums, square))             # [1, 4, 9, 16, 25]
print(process_numbers(nums, cube))               # [1, 8, 27, 64, 125]
print(process_numbers(nums, lambda x: x + 10))  # [11, 12, 13, 14, 15]
```

`process_numbers` doesn't know or care what operation to perform — it delegates that decision to the caller.

### Returning Functions (The Strategy Pattern)

```python theme={null}
def multiplier(factor):
    def multiply(number):
        return number * factor
    return multiply

double = multiplier(2)
triple = multiplier(3)

print(double(10))   # 20
print(triple(10))   # 30
```

### Real-World: Salary Policy Example

```python theme={null}
def process_salary(salary, policy):
    return policy(salary)

def tax(salary):
    return salary * 0.9

def bonus(salary):
    return salary * 1.2

salary = 50000
print(process_salary(salary, tax))    # 45000.0
print(process_salary(salary, bonus))  # 60000.0
```

`process_salary` is generic. Different policies (`tax`, `bonus`) are plugged in at call time — a classic **Strategy Pattern**.

## Built-In Higher-Order Functions

### `map()` — Transform Every Element

```python theme={null}
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x * x, numbers))
print(squared)   # [1, 4, 9, 16]
```

For complex multi-line logic, pass a named function directly:

```python theme={null}
def get_grade(marks):
    if marks >= 90:
        return "A"
    elif marks >= 75:
        return "B"
    elif marks >= 50:
        return "C"
    return "F"

student_marks = [88, 45, 92, 67]
grades = list(map(get_grade, student_marks))
print(grades)   # ['B', 'F', 'A', 'C']
```

### `filter()` — Keep Elements That Match a Condition

```python theme={null}
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)   # [2, 4, 6]
```

### `reduce()` — Collapse a Sequence to a Single Value

```python theme={null}
from functools import reduce

numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)
# Computed as: ((1 * 2) * 3) * 4 = 24
print(product)   # 24
```

## Functional Pipeline: Sum of Squares of Even Numbers

This classic example chains all three higher-order functions together:

```python theme={null}
from functools import reduce

numbers = [1, 2, 3, 4, 5, 6]

# Step 1: filter even numbers  → [2, 4, 6]
evens = filter(lambda x: x % 2 == 0, numbers)

# Step 2: square each value    → [4, 16, 36]
squares = map(lambda x: x ** 2, evens)

# Step 3: sum the squares      → 56
total = reduce(lambda x, y: x + y, squares)

print(total)   # 56
```

As a single chained statement:

```python theme={null}
total = reduce(
    lambda x, y: x + y,
    map(lambda x: x ** 2,
        filter(lambda x: x % 2 == 0, numbers))
)
print(total)   # 56
```

## The Pythonic Equivalent

While the functional pipeline above is correct, Python often provides a more readable alternative using generator expressions and built-in functions:

```python theme={null}
numbers = [1, 2, 3, 4, 5, 6]
total = sum(x ** 2 for x in numbers if x % 2 == 0)
print(total)   # 56
```

<Tip>
  Prefer **generator expressions** and built-in functions (`sum()`, `max()`, `min()`, `all()`, `any()`) for mathematical operations on collections. Use `map()`/`filter()`/`reduce()` when building explicit functional pipelines or integrating with callback-based APIs.
</Tip>
