Functools
Standard module that provides a number of functions that operate on other functions usually returning new ones, somehow modified.
Very useful module. A sign of a good Pythonista. Most useful functions:
partial
reduce
wraps
total_ordering
lru_cache
functools.partial
New function that calls target function with some arguments already set. This gives a copy of a function with less attributes.
🪄 Code:
import functools, math
def string_concatenator(x, y):
return str(x) + str(y)
helloer = functools.partial(string_concatenator, "Hello ")
byer = functools.partial(string_concatenator, y=", Bye-bye, ja nai!..")
print(helloer("World"))
print(byer("Margarita"))
### Using lambda sometimes much better:
h2 = lambda arg: string_concatenator("Hello ", arg)
print(h2("Beatufiul World"))📟 Output:
Hello World
Margarita, Bye-bye, ja nai!..
Hello Beatufiul World🪄 Code:
pow_of_10 = functools.partial(math.pow, 10) # 10 - first arg
pow_of_10.__doc__ = 'Bring 10 to power x'
pow_of_10(5) # 5 - second arg📟 Output:
100000.0What if we want to be able to assign specific positional argument?
It can't be done! Use lambda instead (of even regular def)
🪄 Code:
quadrupler = lambda x: pow(x, 4)
quadrupler(2)📟 Output:
16It is recommended to use lambda instead of functools.partial when possible.
functools.reduce
Apply function of two arguments cumulatively to the items of sequence, from left to right, so as to reduce the sequence to a single value.
In Python 2
functools.reducewas builtin functionreduce
🪄 Code:
import functools
functools.reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])📟 Output:
15🪄 Code:
((((1+2)+3)+4)+5)📟 Output:
15Factorial, "ez mode":
🪄 Code:
# Reminder what is factorial:
((((1 * 2) * 3) * 4) * 5)📟 Output:
120🪄 Code:
functools.reduce(lambda x, y: x * y, range(1,6))📟 Output:
120🪄 Code:
from operator import mul
functools.reduce(mul, range(1,6))📟 Output:
120functools.lru_cache
Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls.
🪄 Code:
@functools.lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print([fib(n) for n in range(20)])
print(fib.cache_info())📟 Output:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
CacheInfo(hits=36, misses=20, maxsize=None, currsize=20)Last updated
Was this helpful?