The functools module
functools holds tools that take functions and return new ones.
from functools import (
lru_cache, partial, reduce)
parse_hex = partial(int, base=16)
print(parse_hex("ff"))
print(reduce(lambda a, b: a * b, [2, 3, 4]))
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(80), fib.cache_info().hits)partialfixes some arguments now and leaves the rest for later.reducefolds an iterable into one value, two items at a time. Give it a start value for empty input.sum,maxor a loop is often clearer.lru_cacheremembers results by argument, so arguments must be hashable.cacheis the same without a size limit.
Choosing by type
from functools import singledispatch
@singledispatch
def show(x):
return repr(x)
@show.register
def _(x: list):
return " | ".join(map(show, x))
print(show([1, "a", [2]]))singledispatch picks an implementation from the type of the first argument. New types can be registered later, without editing a chain of isinstance checks.
Your task
Define parse_binary with partial, so parse_binary("101") is 5. Write product(nums) with reduce, returning 1 for an empty list. Write grid_paths(rows, cols), the number of right-or-down routes across a grid (1 when either side is 1), cached with lru_cache. Write describe(value) with singledispatch: "int 5" for ints, "text 'hi'" for strings and "other" for anything else.
The explanation opens here once every check passes.