← Back to Python Course | Chapter 11: Advanced Python | Lesson 11 of 12

Python functools

functools is a toolbox of helpers for working with functions, like remembering answers so you do not repeat work. It offers shortcuts such as caching and pre-filling arguments.
Syntax
python
from functools import reduce, partial, lru_cache

@lru_cache(maxsize=None)
def function_name(parameter):
    # cached result

new_function = partial(function_name, argument)

Caching with lru_cache

The @lru_cache decorator memoizes a function's return value against its exact arguments, so repeated calls with the same inputs skip recomputation entirely and return the cached result instantly.

This turns naive exponential-time recursive functions, like a plain recursive Fibonacci, into fast linear-time ones with a single decorator.

Example: Caching with lru_cache

python
from functools import lru_cache

@lru_cache  # caches results per set of arguments
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(30))  # fast thanks to cached repeated subcalls

Partial Functions with partial

partial() takes a function plus some of its arguments and returns a new callable with those arguments already locked in, needing only the remaining ones when called.

It's a clean way to specialize a general-purpose function into a narrower one without writing a wrapper def by hand.

Example: Partial Functions with partial

python
from functools import partial

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

square = partial(power, exponent=2)  # locks in exponent=2
print(square(5))  # only base is still needed

Custom Sorting with cmp_to_key

cmp_to_key() bridges old-style two-argument comparison functions (which return negative, zero, or positive) into the single-argument key functions that sorted() and list.sort() expect in modern Python.

It exists mainly for adapting legacy comparison logic that predates Python 3's key-function-only sorting API.

Example: Custom Sorting with cmp_to_key

python
from functools import cmp_to_key

def compare(a, b):  # old-style comparator: negative, zero, or positive
    return a - b

nums = [3, 1, 2]
print(sorted(nums, key=cmp_to_key(compare)))  # adapts it into a modern key function

Wrapping Decorators with wraps

@wraps is applied inside a custom decorator's inner wrapper function, and it copies the original function's __name__, __doc__, and other metadata onto the wrapper.

Without it, decorated functions would misleadingly report the wrapper's own name and docstring instead of the real function's, breaking introspection tools and confusing debugging.

Example: Wrapping Decorators with wraps

python
from functools import wraps

def log(func):
    @wraps(func)  # copies func's __name__ and __doc__ onto wrapper
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@log
def greet():
    """Greets the user."""
    print("hi")

print(greet.__name__, greet.__doc__)  # reports greet's real name and docstring

Accumulating Values with reduce

reduce() repeatedly applies a two-argument function to a running accumulator and each next item in a sequence, collapsing the whole sequence down to one final value.

It's the general-purpose tool behind patterns like summing a list or finding a maximum, though for those specific cases Python's built-in sum() and max() are usually clearer.

Example: Accumulating Values with reduce

python
from functools import reduce

numbers = [1, 2, 3, 4]
total = reduce(lambda a, b: a + b, numbers)  # collapses the list into one accumulated value
print(total)
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using lru_cache on functions with unhashable arguments such as lists, which raises TypeError.
  2. Using lru_cache on functions with side effects, so repeat calls return the cached result and skip the side effect.
  3. Forgetting @wraps(func) in a decorator, which hides the original function's name and docstring.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.