'' == False
>>> 0 == False
>>> 0.0 == False
In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false:
None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their truth value by providing a
Trueif its argument is false,
!=compare the values of two objects. The objects do not need to have the same type.
Because all types are (direct or indirect) subtypes of
object, they inherit the default comparison behavior from
object. Types can customize their comparison behavior by implementing rich comparison methods like
So, the technical implementation answer is that it behaves the way it does because
== use different comparisons.
__bool__, the "truth value" of an object, while
__eq__, the direct comparison of one object to another. So it's possible to ask an object whether it considers itself to be truthy or falsey, and separately from that ask it whether it considers itself to be equal to another object or not. The default implementations for that are arranged in a way that two objects can both consider themselves falsey yet not consider themselves equal to one another.