[str(x) for x in range(100) if x%2 is 0]
VS
map(lambda x: str(x), filter(lambda x: x%2 is 0, range(100)))
[str(x) for x in range(100) if x%2 is 0]
VS
map(lambda x: str(x), filter(lambda x: x%2 is 0, range(100)))
I think this, and the P/S example, are both symptomatic of how Python (anthropomorphized) wants you to think about functions: they're things you stick parens after and call, not things you pass around on their own.
map(str, filter(lambda x: x%2 is 0, range(100)))
1. Transforming a list using some non-standard function, often with some basic input checking:
[int(x)*2+1 for x in seq if x]
(Here, we're assuming x is a string which can possibly be empty or only blanks)2. Transforming elements from multiple lists together:
['Iter %d took %0.2f secs' % (i, t) for i, t in zip(iters, times) if t > 1.5]
(Where we want output strings only if some iteration took a long time)Although I'm not too fluent in lisp, I think the equivalent formulations might be longer (since you'd have to write lambda, map, filter and many parens), and perhaps harder to decipher.
(def vector-dot-product (vector-1 vector-2)
(map [* _1 _2] vector-1 vector-2))
That's from Light Makes Right the raytracer, I think.
Equivalent python: def vectorDotProduct(vector1, vector2):
return [x * y for x, y in zip(vector1, vector2)]
I'm pretty sure that the Lisp snippet above is neither harder to decipher nor longer. Though maybe that's just because Arc is nice.Although ironically in this case, I'd probably use the following:
def vectorDotProduct(vector1, vector2):
return map(op.mul, vector1, vector2)
(where op has been imported previously using: import operator as op
)I'm not really sure how idiomatic this is, but I find that 90% of the time when I use map in python, it's with the operator module.
vectorDotProduct = map (*)
vectorDotProduct = zipWith ( * )
(and this doesn't even include the sum)
map ( * ) has type Num a => [a] -> [a -> a] which is not really what the dot product should be.