map-comprehension is a bad name for that function, since it doesn't give you comprehension-like syntax, instead it is just a function that behaves like map but produces a map instead of another sequence. I'd call it map-map.
This is just a side-effect of bool being a subclass of int and True and False having the values 1 and 0, respectively. It might seem weird or surprising, but it's not a problem with Python's type system.
When is it ever desirable? I'm open to it having a use, but I don't see one. The only thing I've gotten from it is mismatched types that made it past some unit tests but blew up in the real world.
I was making a glib joke, but to answer your question this is the tradeoff of using a not-so-strongly-typed language. Weakly-typed languages often save you some typing (if you'll forgive the pun) and implicitly convert in ways that can make it difficult to prevent those mistakes.
It's just like Duck Typing- you're trading the need to explicitly specify an interface for the potential dangers of letting your interpreter "know what you mean".
If this is frequently a problem, well... there are a lot of strongly-typed languages out there waiting for you to give them a try.
In fact, to expand on the latter part of my comment, "weak typing" is generally understood as implying implicit type coercions or conversions at runtime. PHP and Javascript famously convert between numbers and strings depending on a bunch of factors (and usually the wrong way leading to unreliable results).
In that sense, Python is a very strongly typed language: from the top of my head, the only example of implicit type conversion in Python is the promotion of `int` to `long`, which has been removed from 3.x (all integer types were unified). All other conversions have to be explicit as far as I remember. That makes Python more strongly (but less statically) typed than Java (see the very strange overloading of the `+` operator when any operand is a string, as well as autoboxing since 1.5) and C# (C# allows for implicit type conversions, including in userland, and the cast operator doubles up as an explicit type conversion operator which I find terrible)
Python is fairly strongly typed in general. (At least compared to Perl and the like. Examples like True + True notwithstanding.) It is just also very dynamic.
This is only tangentially related, but try looking up "Iverson brackets" and Knuth's "Two notes on notation". One argument there is that False - True = -1 makes sign(x) = [x > 0] - [x < 0], which is convenient. I don't know of a case where True + True = 2 helps, but maybe something involving dual sums would be relevant.
The Iverson Bracket would already exist in a python that didn't subclass bool from int; '[boolean_expression]' would be, in python notation: 'int(boolean_expression)'.
Sounds kinda like I'm making the same argument as Knuth in forcing '[]' over '()'.
The greatest hidden feature of Python (for me) was its standard library. Its sheer size and completeness, I should add.
Yes, I have heard of "batteries included" and all, but after working with Python for a year I still felt that the size of its library has been "hidden" from general programming public.
You can add the number of Python implementation to your list of "hidden" features as well: IronPython, CPython, Jython, PyPy, unladen-swallow, Python3 - and all of them are of pretty high quality!
I feel validated that the chaining comparison operators feature is #1 in terms of votes (303 vs #2 at 249 as I write this). Nobody else seems to think it worth mentioning, but chaining comparison operators is a feature I'm really fond of in Lisp/Scheme: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node124.html
I wouldn't say Lisp has chaining of comparisons, only chaining of identical comparisons: a < b < c --> (< a b c), but a < b <= c --> (and (< a b) (<= b c))