@that other guy already pointed out the issue, I figured I'd add a bit of explanation for those that don't see the point.
The key thing to realise here is that is not
is similar to !=
and in
is also in the same category - they are all comparison operators https://docs.python.org/2/reference/expressions.html#comparisons. And these operators work for all the types of the values surrounding them.
Because Python allows chaining comparison operators, the main thing is to figure out the order in which they will be evaluate and what they operate on.
Consider:
>>> "asdf" in {} is not None
False
>>> ("asdf" in {}) is not None
True
>>> ("asdf" in {}) and ({} is not None)
False
>>> {} is not None
True
So, the expression "asdf" in {} is not None
breaks down into <value> <comparison> <value> <comparison> <value>
, which Python evaluates as <value1> <comparison> <value2> and <value2> <comparison> <value3>
, so ("asdf" in {}) and ({} is not None)
.
The reason Python doesn't see it as ("asdf" in {}) is not None
, which makes sense coming from some other languages, is that Python doesn't want 4 > 3 > 2
to evaluate as (4 > 3) > 2
(which is False
), but as (4 > 3) and (3 > 2)
(which is True
).
<x> is not None
by the way means the identity of <x> is the same as the identity of None
, in other words "<x>
refers to the same thing as None
", which is slightly different from saying they have the same value (or "they evaluate to the same"). Since there is only one None
, if a variable name refers to None
it is None
.