118

As far as I know, in C & C++, the priority sequence for NOT AND & OR is NOT>AND>OR. But this doesn't seem to work in a similar way in Python. I tried searching for it in the Python documentation and failed (Guess I'm a little impatient.). Can someone clear this up for me?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Akshar Gupta
  • 1,281
  • 2
  • 9
  • 3

8 Answers8

143

It's NOT, AND, OR, from highest to lowest according to the documentation on Operator precedence

Here is the complete precedence table, lowest precedence to highest. A row has the same precedence and groups from left to right

 0. :=
 1. lambda
 2. if – else
 3. or
 4. and
 5. not x
 6. in, not in, is, is not, <, <=, >, >=, !=, ==
 7. |
 8. ^
 9. &
10. <<, >>
11. +, -
12. *, @, /, //, %
13. +x, -x, ~x
14. **
14. await x
15. x[index], x[index:index], x(arguments...), x.attribute
16. (expressions...), [expressions...], {key: value...}, {expressions...}
Mathias711
  • 6,568
  • 4
  • 41
  • 58
Kyle Heuton
  • 9,318
  • 4
  • 40
  • 52
  • 2
    Note that `**` has some exceptions noted in a footnote when it comes to precedence over arithmetic operators. – Martijn Pieters May 21 '13 at 21:09
  • 1
    This confuses the mathematician in me: in arithmetic, we would say it has precedence over arithmetic operators. On its right, the `**` operator does not have precedence over arithmetic operations, but it has on its left... For example, `5*2**2 == 5*(2**2)`. However it is right to say that `2**-1 == 2**(-1)`. – PhilMacKay Sep 05 '18 at 13:51
  • 1
    @PhilMacKay - it might seem, that e.g. the minus is part of the `int` literal, but when parsing it with `ast` it's not the case - it's `UnaryOp` with `USub` and `1` as operand. The real reason is, there is no other way to parse it. I.e. `2**` is not a correct left operand for binary minus. Thus "exponentiation priority exception", but "only on the right". – Tomasz Gandor Oct 28 '19 at 16:38
42

You can do the following test to figure out the precedence of and and or.

First, try 0 and 0 or 1 in python console

If or binds first, then we would expect 0 as output.

In my console, 1 is the output. It means and either binds first or equal to or (maybe expressions are evaluated from left to right).

Then try 1 or 0 and 0.

If or and and bind equally with the built-in left to right evaluation order, then we should get 0 as output.

In my console, 1 is the output. Then we can conclude that and has higher priority than or.

nos
  • 19,875
  • 27
  • 98
  • 134
  • 8
    More explicitly, the expressions are evaluated as: `((0 and 0) or 1)` and `(1 or (0 and 0))` – Conchylicultor Dec 17 '19 at 23:08
  • 2
    However, in the second expression, the `(0 and 0)` is never evaluated as `(exp1 or exp2)` directly return if `exp1` is `True`. Similarly in the first expression, the `and 0` part is never evaluated as `exp1 and exp2` directly return if `exp1` is `False`. – Conchylicultor Dec 17 '19 at 23:25
22

not binds tighter than and which binds tighter than or as stated in the language reference

mgilson
  • 300,191
  • 65
  • 633
  • 696
6

Of the boolean operators the precedence, from weakest to strongest, is as follows:

  1. or
  2. and
  3. not x
  4. is not; not in

Where operators are of equal precedence evaluation proceeds from left to right.

Oswald Wirt
  • 61
  • 1
  • 2
  • Sorry your #2 is technically correct but still very misleading. First of all, the doc doesn't seem to change. Secondly, your opinion #2 (suggesting `and` & `not x` is evaluated from left to right) is technically equivalent to the official effect, but that is simply because when in "cond1 and not cont2", python has to calculate cont2 first by default. – RayLuo Apr 25 '15 at 19:00
  • Thanks @RayLuo, but it wasn't even _technically_ correct. I was placing meaning in the incorrectly rendered lines dividing the rows in that table. Looking at the 2.7 doc _today_ `or` and `and` appear to be in the same cell using _Firefox_ but not _Opera_ . The difference in precedence between `or` and `and` is obvious (eg. `1 or 0 and 0` vs `(1 or 0) and 0`) that between `and` and `not x` not so much for the reason you give. I'll repair my answer to reflect what the documentation _actually_ says. – Oswald Wirt Jul 24 '15 at 05:17
6

Some simple examples; note the operator precedence (not, and, or); parentheses to assist human-interpretability.

a = 'apple'
b = 'banana'
c = 'carrots'

if c == 'carrots' and a == 'apple' and b == 'BELGIUM':
    print('True')
else:
    print('False')
# False

Similarly:

if b == 'banana'
True

if c == 'CANADA' and a == 'apple'
False

if c == 'CANADA' or a == 'apple'
True

if c == 'carrots' and a == 'apple' or b == 'BELGIUM'
True

# Note this one, which might surprise you:
if c == 'CANADA' and a == 'apple' or b == 'banana'
True

# ... it is the same as:
if (c == 'CANADA' and a == 'apple') or b == 'banana':
True

if c == 'CANADA' and (a == 'apple' or b == 'banana'):
False

if c == 'CANADA' and a == 'apple' or b == 'BELGIUM'
False

if c == 'CANADA' or a == 'apple' and b == 'banana'
True

if c == 'CANADA' or (a == 'apple' and b == 'banana')
True

if (c == 'carrots' and a == 'apple') or b == 'BELGIUM'
True

if c == 'carrots' and (a == 'apple' or b == 'BELGIUM')
True

if a == 'apple' and b == 'banana' or c == 'CANADA'
True

if (a == 'apple' and b == 'banana') or c == 'CANADA'
True

if a == 'apple' and (b == 'banana' or c == 'CANADA')
True

if a == 'apple' and (b == 'banana' and c == 'CANADA')
False

if a == 'apple' or (b == 'banana' and c == 'CANADA')
True
Victoria Stuart
  • 4,610
  • 2
  • 44
  • 37
2

There is no good reason for Python to have other priority sequence of those operators than well established one in (almost) all other programming languages, including C/C++.

You may find it in The Python Language Reference, part 6.16 - Operator precedence, downloadable (for the current version and packed with all other standard documentation) from https://docs.python.org/3/download.html, or read it online here: 6.16. Operator precedence.

But there is still something in Python which can mislead you: The result of and and or operators may be different from True or False - see 6.11 Boolean operations in the same document.

MarianD
  • 13,096
  • 12
  • 42
  • 54
0

not > and

print(~0&0) # 0

and > or

print(0&0|1) # 1
Yas
  • 4,957
  • 2
  • 41
  • 24
-2

Expression 1 or 1 and 0 or 0 returns 1. Looks like we have the same priority, almost same.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 21 '21 at 13:29