List comprehensions are more flexible and easier to read in the non-trivial case. Sure in the trivial case you show a map might be considered neater, but just adding a filter is enough to make the list comprehension more readable in my mind. Python's lambda syntax also makes using maps and filters quite ugly.
Don't forget generator comprehensions which are almost identical to list comprehensions. But instead of evaluating the whole result set and returning it, they return a generator that you can then iterate over. Very neat stuff.
Even with named functions, Python's use of global functions instead of methods for iterators force you to read the expression from the inside out. I think Lisp languages nailed this with their threading macros, which allow natural left-to-right reading, but Ruby's strategy is better than Python's, too, while maintaining very similar syntax.
That being said, my Python is limited and I don't know it filter/map are available as methods of a list. At the end of the day, there are cases where list comprehensions are much cleaner/understandable... and cases where the reverse is true.
> I don't know it filter/map are available as methods of a list.
They're not. Which is a shame in my opinion, because as you've written it you can clearly read the operations in the order they happen, ie. filter followed by map. Instead, you do have to do the second line of what blossoms wrote above.
And I don't think it's possible to write a list comprehension that reads in execution order, either :(
It's not like list comprehensions lack equivalent in other languages. Let's take Haskell for example.
Python lists comprehension could use a where clause from Haskell though so one could really pack everything into a one-liner :)
(as it is now, list comprehensions requiring various references to result of a function call evaluate the function each time it's used)
you can consider a list comprehension to be a sort of literal representation of the result of map. I think literals have a benefit for code readability and should be used when feasible (i.e. the literal is compact enough).
the other reason its considered more idiomatic in Python is just because the compiler does a better job of parsing and optimizing list comprehensions.
You use list comprehensions in other places you wouldn't use map. The difference in text size as you posted is minimal, but the list comprehension - once you're used to reading them - tells you exactly what's going on.
Where as map could be anything. It could be redefined for all you'd know.
Don't know if this is why, but the list comprehension takes an expression at the "foo(word)" location, and is therefore more general than map, which requires a function. The comprehension in that case is simpler.
words = ['w1', 'w2', 'w3']
[word[1] for word in words]
['1', '2', '3']
map(lambda x: x[1], words)
['1', '2', '3']
I like looking at the list comprehension better. The use of lambda looks forced in this case. I also imagine there's a penalty for calling the (anonymous) function in map.