11

Does python support chaining is operators, such as the following?

a = None
b = None
a is b is None

This outputs True, some doc references would be nice.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
simonzack
  • 19,729
  • 13
  • 73
  • 118
  • What is your question, exactly? Note that you will get different results for comparing identity rather than equality if you move away from singletons and interned integers. – jonrsharpe Aug 03 '14 at 09:01
  • See my use case, same to that of 1 <= 2 <= 3. – simonzack Aug 03 '14 at 09:04
  • The answer to the question *"Does python support chaining `is` operators"* is, as demonstrated by your testing, "yes", so I'm wondering what you still want to know. – jonrsharpe Aug 03 '14 at 09:07
  • 1
    @jonrsharpe I wanted to know the exact semantics. – simonzack Aug 03 '14 at 09:10
  • 4
    @jonrsharpe It’s valid to question behaviour which seems to be valid at the first sight, and seek validation from the docs. Otherwise, bugs might creep in and bad software gets written. So +1 for the question! – Jonas Schäfer Aug 03 '14 at 09:10
  • Does this answer your question? ["is" operator behaves unexpectedly with integers](https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers) – Jossie Calderon Jun 03 '20 at 02:37

4 Answers4

16

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 to a 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.

user2357112
  • 260,549
  • 28
  • 431
  • 505
3

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.

Community
  • 1
  • 1
miles82
  • 6,584
  • 38
  • 28
3

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
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
1

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

Paul Hankin
  • 54,811
  • 11
  • 92
  • 118