Ignoring Python for a bit and thinking as a designer of some hypothetical future language: there is a nice rule given here for evaluation in a Boolean context. I wonder whether it should be taken as a general guideline for future languages.
The rule, in its entirety, is this:
- Booleans are falsy when false.
- Numbers are falsy when zero.
- Containers are falsy when empty.
- None is always falsy.
- No other type of value is ever falsy.
I can think of two ways we might possibly want to alter the rule.
The first is to expand the idea of number to include arbitrary groups (or monoids?), with the identity element being falsy. So, for example, a matrix with all entries zero might be falsy. Or a 3-D transformation might be falsy if it does not move anything.
The second is one I have encountered in C++. There, an I/O stream is falsy if it is in an error state. This makes error checking easy; there is one less member-function name to remember. We might expand this idea to include things like Python's urllib, or any object that wraps a connection or stream of some kind.
EDIT: OTOH, there is the Haskell philosophy, where the only thing that can be evaluated in a Boolean context is a Bool, so the only falsy thing is False.
EDIT 2: The comment by clarkevans (quoting a message from INADA Naoki) already partially addressed the above group idea: "I feel zero value of non abelian group should not mean False in bool context."