reduce is a pretty nice built-in, but its usage in everyday code is seemingly rare. If you've been looking for excuses to use reduce, here are a few useful recipes to get you started.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import operator
def factorial(n):
"""Calculate n factorial"""
return reduce(operator.mul, range(2, n+1), 1)
def intersection(*sets):
"""Get the intersection of all input sets"""
return reduce(set.intersection, sets)
def union(*sets):
"""Get the union of all input sets"""
return reduce(set.union, sets)
def join(*seqs):
"""Join any input sequences that support concatenation"""
return reduce(operator.concat, seqs)
"""
Some usage:
>>> factorial(3)
6
>>> factorial(10)
3628800
>>> a = set([1, 2, 3, 4, 5])
>>> b = set([5, 6, 3, 7])
>>> c = set([8, 7, 5])
>>> intersection(a, b, c)
set([5])
>>> union(a, b, c)
set([1, 2, 3, 4, 5, 6, 7, 8])
>>> join("one", "two", "three", "four")
'onetwothreefour'
>>> join([1, 2, 3], [5, 6], [6, 7])
[1, 2, 3, 4, 5, 6, 7]
"""
|
If you post a clever way to use reduce to solve a common problem, post it here and I'll add it to the recipe.
Tags: shortcuts
Chained replacements in a string. One way that I've recently found to use reduce is for the chained replacement of characters in a string.
So instead of:
I use:
And an example:
Ironically enough, on my machine the the reduce version is about 37% slower than the looped version on the example I gave above.
Anonymous in-line list comprehension functions. Python is a wonderfully expressive programming language. Some expressions such as those involving reduce, are more elegant and simple than others. I enjoy and value the functional facilities and functions as first class objects in Python. I have, however, seen evidence that some of these are in jeopardy (google for The fate of reduce() in Python.)
Here are in-line list comprehension versions of your functions and a bit more. The general form is: set initial value, set iteration values and successively apply an infix or prefix function cumulatively and finally take the last value of the generated list.
And for predicates.
Use reduce to call divmod with succesive divisors. I used reduce to build up a tuple of the parts of an elapsed time, starting with a floating point number of seconds. Posted at recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/511486
-- Paul