"Collapsing" a list into a list of changes
Steven Bethard
steven.bethard at gmail.com
Mon Feb 7 14:41:59 EST 2005
John Lenton wrote:
> For example, the fastest way
> to get the factorial of a (small enough) number in pure python is
>
> factorial = lambda n: reduce(operator.mul, range(1, n+1))
Gah! I'll never understand why people use lambda, which is intended to
create _anonymous_ functions, to create named functions! This code is
basically equivalent to:
def factorial(n):
return reduce(operator.mul, range(1, n+1))
except that factorial.__name__ is now the meaningful 'factorial',
instead of '<lambda>'. See "Inappropriate use of Lambda" in
http://www.python.org/moin/DubiousPython
My personal beef with the inappropriate use of lambda aside, and
ignoring the fact that the reduce solution as written fails for
factorial(0), some timings are in order. Given fact.py:
----------------------------------------------------------------------
import operator
def f1(n):
result = 1
for x in xrange(1, n+1):
result *= x
return result
def f2(n):
return reduce(operator.mul, range(1, n+1))
def f3(n):
return reduce(operator.mul, xrange(1, n+1))
----------------------------------------------------------------------
I get the following timeit results (with Python 2.4):
$ python -m timeit -s "import fact" "[fact.f1(x) for x in xrange(1, 100)]"
100 loops, best of 3: 2.53 msec per loop
$ python -m timeit -s "import fact" "[fact.f2(x) for x in xrange(1, 100)]"
100 loops, best of 3: 2.46 msec per loop
$ python -m timeit -s "import fact" "[fact.f3(x) for x in xrange(1, 100)]"
100 loops, best of 3: 2.17 msec per loop
So it does look like reduce is actually faster in this case, especially
if you use xrange instead of range.
Thanks for the example!
Steve
More information about the Python-list
mailing list