Steven D'Aprano wrote: > On Fri, 01 Jul 2005 12:24:44 -0700, Devan L wrote: > > >>With the exception of reduce(lambda x,y:x*y, sequence), reduce can be >>replaced with sum, and Guido wants to add a product function. > > > How do you replace: > > reduce(lambda x,y: x*y-1/y, sequence) > > with sum?
You don't, but an almost equally short replacement works just as well, and doesn't even need the lambda: >>>sequence=range(1,100) >>>_res = 0.0 >>>for x in sequence: _res = _res*x + 1/x >>><blank line if in interactive mode> >>>_res 9.3326215443944096e+155 Sure, this isn't a sum, but I'd argue that the for loop solution is superior: 1) For single expressions, the guts of the operation is still a single line 2) This completely avoids lambda -- while I myself am ambivalent about the idea of lambda going away, lambda syntax can get hairy for complicated expressions -- the comma changes meaning halfway through the expression, from 'parameter delimiter in lambda' to 'next parameter in reduce' 3) This trivially extends to a block of code, which a lambda doesn't 4) Behavior for zero- and one-length lists is explicit and obvious. There are, of course, a few disadvantages, but I think they're more corner corner cases. 1) This solution obviously isn't itself an expression (although the result is a single variable), so it can't be used in totality as a component to a larger call. [Rebuttal: When exactly would this be a good thing, anyway? Reduce statements are at least 11 characters long, 13 with a one-character default value. Using this as a parameter to just about anything else, even a function call, seems a bit unreadable to me.] 2) An explicit intermediate/result value is needed. This seems to be more of a 'cleanliness' argument than anything. Besides, rewriting this as a for loop actually improves performance: >>> sequence = range(1,100) >>> def f1(): j = 0.0 for x in sequence: j = j*x+1/x return j >>> def f2(): return reduce(lambda x,y: x*y - 1/y, sequence) >>> def runtime(f,n): starttime = time.time() for i in xrange(n): f() print time.time()-starttime >>> runtime(f1,10000) 1.37199997902 >>> runtime(f2,10000) 3.67499995232 Making the series bigger results in even worse relative performance (no idea why): >>> sequence = range(1,1000) >>> runtime(f1,10000) 18.4169998169 >>> runtime(f2,10000) 125.491000175 So really, 'reduce' is already useless for large anonymous blocks of code (which can't be defined in lambdas), and it seems slower than 'for .. in' for even simple expressions. -- http://mail.python.org/mailman/listinfo/python-list