Python - Functional & Advanced

Overview

Estimated time: 45–60 minutes

Use functional tools and advanced language features to write concise, efficient, and expressive code.

Learning Objectives

  • Use lambdas and built-ins (map, filter, any/all, sum).
  • Compose iterators with itertools; cache and dispatch with functools.
  • Create and apply decorators for cross-cutting concerns.

Prerequisites

Lambdas and built-ins

nums = [1,2,3,4]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens)
print(any(x > 3 for x in nums))

Expected Output: [2, 4]\nTrue

itertools

import itertools as it
print(list(it.islice(it.count(10, 2), 3)))  # 10,12,14

Expected Output: [10, 12, 14]

functools

from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n: int) -> int:
    return n if n < 2 else fib(n-1) + fib(n-2)

print(fib(10))

Expected Output: 55

Decorators

from functools import wraps

def log_calls(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        print(f"calling {fn.__name__}")
        return fn(*args, **kwargs)
    return wrapper

@log_calls
def hello():
    print("hello")

hello()

Expected Output: calling hello\nhello

Common Pitfalls

  • Overusing lambdas when a named function improves clarity.
  • Forgetting @wraps in decorators, losing metadata.

Checks for Understanding

  1. What does lru_cache do?
  2. Why use @wraps in a decorator?
Show answers
  1. It memoizes function results up to a max size.
  2. To preserve the original function’s metadata (name, docstring).

Exercises

  1. Write a decorator that times function execution and prints the duration.
  2. Use itertools.groupby to group words by first letter.