Chaining "is" operators
Yes. Any operators classified as comparisons can be chained. From the language reference:
Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then
a op1 b op2 c ... y opN z
is equivalent toa op1 b and b op2 c and ... y opN z
, except that each expression is evaluated at most once.
The comparison operators are <
, >
, ==
, >=
, <=
, <>
(a little-used synonym for !=
, gone in Python 3), !=
, is
, is not
, in
, and not in
.
Yes. See comparison docs.
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
What the is comparison operator does:
The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.
Referencing the Python grammar documentation, which is read by Python to parse source files (so this is the source):
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
expr (comp_op expr)*
should read, in plain English, "any number of expressions separated by a comparison operator," of which is
is one. This means that yes, you can chain any number of is
comparisons together.
To demonstrate that the comparisons are chained:
>>> a = b = c = 'foo'
>>> a is b
True
>>> a is b is c
True
>>> True is c
False
Yes, is
is a comparison operator, and the formal description of chaining is in the reference manual.
https://docs.python.org/2/reference/expressions.html#not-in