Plus, you get 5 mentions (3 y's and 2 x's) of some intermediate variables instead of 0 in your code, so both token-wise and char-wise, map/filter alternative is shorter, and less a mental burden (think about the "succinct" idea by PG).
Plus, you get 5 mentions (3 y's and 2 x's) of some intermediate variables instead of 0 in your code, so both token-wise and char-wise, map/filter alternative is shorter, and less a mental burden (think about the "succinct" idea by PG).
If you can put together a nontrivial usage of map+filter with at least three source collections that's more concise than the equivalent list comprehension I'll (figuratively) eat my hat.
map(lambda (w,s,l): {'widget': w, 'sprocket': s, 'location': l}
filter(lambda (w,s,l): l.hasInStock(w) and l.hasInStock(s) and w.isUsableWith(s),
product(widgets, sprockets, locations)))
Well, I agree it is not any conciser that its list comprehension (about the same I guess?). Nothing is perfect, like you said, know you tool :)The argument in favor of set-notation being higher level is it's less specific (it doesn't explicitly provide a sequence of operations, just an outcome).
List comprehensions look like set notation but have an implicit procedural translation you have to keep in mind to use them well, so it's a toss-up.
I prefer map/filter/reduce when sequencing has large performance implications but for simple filtering or raw-data-shaping comprehensions read more smoothly.
Now you know why many people like me are gradually pissed off by Python and start the exile ... currently trying Scala and it seems a nice language (with list comprehension too! :)
> List comprehensions look like set notation but have an implicit procedural translation you have to keep in mind to use them well, so it's a toss-up.
Actually I think that's the problem I have with list comprehensions: I use them a lot in my code, usually 1~3 levels nested and then have a hard time tracking down the order of implicit loops (which is inner vs outer) and make sure the intermediate variables (x for x in y for y in z ...) do not clash ... OK maybe I'm using it too much and in the wrong way :(
> I prefer map/filter/reduce when sequencing has large performance implications but for simple filtering or raw-data-shaping comprehensions read more smoothly.
I didn't know map/filter is faster than list comprehensions? I thought both are optimized by Python interpreter. But I like the idea of knowing that at least map can be parallelized easily. But since Python does not utilize multicore in a decent way, all bets are off :(
do { w <- widgets;
s <- sprockets;
l <- locations;
guard (l `hasInStock` w);
guard (l `hasInStock` s);
guard (w `isUsableWith` s);
return (w, s, l); }
We're trading horizontal space for vertical space. I think it's much clearer than either list comprehensions or plain map/filters. It's the best of both worlds.If eg I edited it to be:
do { l <- locations;
w <- widgets;
guard (l `hasInStock` w);
s <- sprockets;
guard (l `hasInStock` s);
guard (w `isUsableWith` s);
return (w,s,l); }
Does that force it to go through "location-first" and only check the w and s of (w,s,l) for compatibility if it has already ascertained that w and s are in stock @ l?List comprehensions: the set contains this.
Map/filter: apply these functions to the set.
Procedural: follow this recipe for turning one list into another.
[fn(x) for x in xs for xs in xss if cond(xs)]
I always think it's a loop, then an inner loop (and loops -> procedure ... then get confused which is inner and which is outer :|