Factorials

Terry Reedy tjreedy at udel.edu
Tue Jun 10 11:01:07 EDT 2003


"Anand Pillai" <pythonguy at Hotpop.com> wrote in message
news:84fc4588.0306100413.1125d1ee at posting.google.com...
> Here is a version that will make the "functional programmers"
> happy. It is iterative rather than recursive.

That will make some "functional programmers" unhappy, but let each
speak for his/herself.

> def fac1(x):
>     nums=range(x+1)
>     return reduce(lambda x, y: x*y, nums[1:])
..
> def fac1(x): return reduce(lambda x, y: x*y, (range(x+1))[1:])

No reasons to construct two lists: range(x+1)[1:] == range(1,x+1)
No reason for lambda either:  import operator, then operator.mul is C
coded multiplier which should be noticably faster that Python coded
lambda
Also, reduce croaks on empty list, so if you want fact(0) == 1, [as
needed, for instance in C(n,k) = n!/((n-k)!k!) ], you need starter
value 1, in which case, initial 1 in list is not needed.  These all
give

import operator
def fac1(x): return reduce(operator.add, range(2,x+1), 1)

This will, however, not raise exception for negative x but return 1
instead.  Also range allows but truncates float args, so that
fact1(float) = fac1(int(float)) rather than raising exception or
returning float version from gamma function.  So, giving up one-line
fetish, we might write

def fac1(n):
  if n < 0 or int(n) != n: raise ValueError("arg %g is not nonnegative
int" % n)
  else: return reduce(operator.add, range(2,x+1), 1)

Terry J. Reedy






More information about the Python-list mailing list