Edit: Just realized you might be pointing this out to help the interested reader, I first assumed you were reprimanding for reposting.
Timeit's time for three functions:
Lazy Programmer - 0.907521744301
Lazier Programmer - 1.0473810545812512
Using math.factorial - 0.12187403971609001
There's a joke in there somewhere...
import operator as op
import functools as f
fact = lambda x: f.reduce(op.mul, range(1, x + 1))
print(fact(6))
If you're using Python 2.x, you can make it a bit shorter due to reduce being in the default namespace: import operator as op
fact = lambda x: reduce(op.mul, xrange(1, x + 1))
print fact(6) from math import gamma
def factorial(x):
return gamma(x+1)
This has the advantage of working correctly for non-integer arguments.Edit: The math module has a factorial() function anyways, so it's a bit of a moot point. Use that :)
Edit Edit: Thanks for the catch, I did mean non-negative integers instead of positive.
(Of course, this is a silly problem.)
bc = [124, 0, 0, 114, 37, 0, 116, 0, 0, 124, 0, 0, 106, 2, 0, 100, 1, 0, 131, 1,
0, 124, 1, 0, 106, 1, 0, 124, 0, 0, 131, 1, 0, 131, 2, 0, 83, 124, 1, 0,
83]
fact = type(lambda:0)(type((lambda:0).func_code)(2, 2, 7, 0,
''.join(map(chr, bc)), (None, 1), ('fact', '__mul__', '__sub__'),
('x', 'acc'), "n/a", "fact", 0, ""),
globals(), "fact", (1,))As for this not being pythonic, at least its not self modifying or anything fun. I did once see a talk on obsfucated python that used decorators to implement a Turing complete language, so this is hardly the worst abuse of python ever.
(Haskell)
print reduce(lambda x, y: x*y, xrange(2, 6+1))
As a newish Python guy (5 months), I'm interested as to why the preferable solution seems to be to import operator and use the multiplication function? (I'm purposely ignoring the more preferable call to the C library)1) The Python community doesn't really like lambdas. It's almost always considered better style to declare a named function, even if it's a short one-liner. If it's already available in the standard library, use that instead of re-implementing it as an unnecessary lambda.
2) This is an adaptation of jokes that have been made about many languages before Python, so the code isn't very Pythonic to start with. Most of the complex ones have errors that prevent them from running, they're just for comedic effect.
we can use these ideas to elegantly solve the second greplin challenge question: "find the smallest prime fibonacci, X, greater than 227,000; compute sum of prime divisors of X+1"
pred = lambda x: x > 227000 and is_prime(x)
X = take(lazy_filter(pred, fib_gen()), 1)[0]
print sum(filter(is_prime, divisors(X+1)))
https://github.com/dustingetz/sandbox/blob/master/etc/grepli... class Factorial(object):
def __init__(self):
self.n = 0
self.fact_n = 1
def next_fact(self):
self.fact_n *= (self.n + 1)
self.n += 1
def prev_fact(self):
self.fact_n /= self.n
self.n -= 1
def fact(self, n):
if n == self.n:
return self.fact_n
elif n > self.n:
# start from self.n working forward
self.next_fact()
return self.fact(n)
else:
# start from fact_n working backwards
self.prev_fact()
return self.fact(n)
fobj = Factorial()
print fobj.fact(6)
print fobj.fact(8)
print fobj.fact(3)Tangential, but this is why NumPy totally changed my workflow. I can use all of the benefits of Python, including its libraries and syntax, and still have a program that executes at the speed of C, rather than Python[1].
[1] Not literally the speed of C, but you get the idea.
#Python hacker
<function omitted>
sys.stdout.write(str(fact(6)) + '\n')
The call to str is unneeded. For consistency, it should be sys.stdout.write(fact(6).__str__() + "\n")
And if that example want's to be really "hacker"ish, then every function call should actually be a call to the __call__ method of each object.So true...