Python’s order of operations follows the PEMDAS rule from math class: parentheses first, then exponents (**), then multiplication and division, then addition and subtraction, working left to right within each level.
2 + 3 * 4 # 14, not 20
(2 + 3) * 4 # 20
I checked every expression on Python 3.12.5, so the results below are exactly what Python prints, including a few that surprise people.
Below you’ll find PEMDAS in Python, the exponent quirks, floor division and modulo, how and, or and not rank, a full precedence table, and the gotchas worth memorizing.
PEMDAS: the order of operations in Python
You’ll find multiplication and division run before addition and subtraction. Operators on the same level, like - and -, run left to right:
print(2 + 3 * 4) # 14: multiplication first
print((2 + 3) * 4) # 20: parentheses first
print(10 - 4 - 3) # 3: same level goes left to right
print(100 / 10 / 5) # 2.0
print(2 + 10 / 4 * 2) # 7.0: / and * left to right, then +
subtotal, tax_rate, shipping = 80.00, 0.0825, 5.99
print(f"wrong: ${subtotal + subtotal * tax_rate + shipping * 2:.2f}") # ships twice
print(f"right: ${(subtotal * (1 + tax_rate) + shipping):.2f}")
Output:
14
20
3
2.0
7.0
wrong: $98.58
right: $92.59

When a formula involves money, I add parentheses even where they aren’t strictly needed. They cost nothing and make the intent obvious.
Exponent precedence: why -2 ** 2 is -4
** binds tighter than a minus sign on its left, and it groups from right to left. Both rules can catch you out:
print(2 ** 3 ** 2) # 512: ** groups right to left, 2 ** 9
print((2 ** 3) ** 2) # 64
print(-2 ** 2) # -4: the minus applies after **
print((-2) ** 2) # 4
print(2 ** -1) # 0.5: a unary minus on the right is fine
Output:
512
64
-4
4
0.5

2 ** 3 ** 2 means 2 ** 9. To square a negative number, wrap it: (-2) ** 2.More on powers and roots in exponents in Python.
Floor division and modulo precedence
// and % sit on the same level as * and /, so they’re evaluated left to right with them. Watch what happens when you use negative numbers:
print(7 // 2 * 2) # 6: // and * share a level, left to right
print(7 % 3 * 2) # 2
print(-7 // 2) # -4: floor division rounds down, not toward zero
print(-7 % 3) # 2
print(17 - 17 // 5 * 5) # 2, same as 17 % 5
Output:
6
2
-4
2
2
If -7 // 2 giving -4 surprises you, see normal division vs floor division.
Order of and, or and not in Python
not runs first, then and, then or. Comparisons all rank above them, and they chain, so 1 < age < 21 works like it does in math:
age, member = 17, True
print(age >= 18 or member and age > 15) # or (and ...) -> True
print((age >= 18 or member) and age > 15) # True
print(not age > 18 and member) # (not ...) and ... -> True
print(1 < age < 21) # chained: 1 < age and age < 21
print(1 == 1 in [1]) # chained: (1 == 1) and (1 in [1])
flags = 6
print(flags & 2 == 2) # & binds tighter than ==, so this is (6 & 2) == 2
print(flags & (2 == 2)) # 6 & True -> 0
Output:
True
True
True
True
True
True
0

flags & 2 == 2 is True because & runs before ==, but adding the wrong parentheses gives 0.There’s a whole guide on and, or and not in Python, including short-circuiting.
Python operator precedence table
Here’s the full order you can bookmark, from the operators that bind tightest to the loosest. Operators in the same row share a level:
| Precedence | Operators | Description |
|---|---|---|
| 1 (highest) | ( ), [ ], { } | Grouping, displays |
| 2 | x[i], x(...), x.attr | Subscription, calls, attributes |
| 3 | await x | Await expression |
| 4 | ** | Exponent (right to left) |
| 5 | +x, -x, ~x | Unary plus, minus, bitwise not |
| 6 | *, /, //, %, @ | Multiply, divide, floor divide, modulo |
| 7 | +, - | Add, subtract |
| 8 | <<, >> | Bit shifts |
| 9 | & | Bitwise AND |
| 10 | ^ | Bitwise XOR |
| 11 | | | Bitwise OR |
| 12 | in, not in, is, is not, <, <=, >, >=, !=, == | Comparisons (they chain) |
| 13 | not | Boolean NOT |
| 14 | and | Boolean AND |
| 15 | or | Boolean OR |
| 16 | x if c else y | Conditional expression |
| 17 | lambda | Lambda |
| 18 (lowest) | := | Assignment expression (walrus) |
Which operator precedence mistakes are most common?
The conditional expression and the walrus operator both sit near the bottom, so they swallow more than you might expect. Your string expressions follow the same rules too:
price = 120.00
label = "free shipping" if price > 100 else "standard" + " shipping"
print(label) # the + only belongs to the else part
items = [4.50, 2.75, 3.25]
if (count := len(items)) > 2: # := needs parentheses here
print(count, "items")
s = "Austin"
print("Hi " + s * 2) # * before +
print(not "" == "x") # not (... == ...) -> True
Output:
free shipping
3 items
Hi AustinAustin
True
In the first line, + " shipping" only attaches to the else branch. For more on conditions, see if else in Python and does not equal in Python.
Related operator guides worth reading:
- What does in mean in Python
- Increment and decrement operators
- Exponential functions in Python
- Convert an int to a string
Frequently asked questions
What is the order of operations in Python?
Parentheses, exponents, multiplication and division (including // and %), then addition and subtraction, left to right within each level.
Does Python follow PEMDAS?
Yes for arithmetic. Python then adds more levels for bitwise, comparison and boolean operators.
Why is -2 ** 2 negative in Python?
Exponentiation binds tighter than the unary minus on its left, so it’s read as -(2 ** 2).
Is ** left or right associative?
Right associative: 2 ** 3 ** 2 is 2 ** (3 ** 2), which is 512.
Which comes first, and or or?
and. So a or b and c means a or (b and c). not comes before both.
Where is the official precedence table?
See the operator precedence section of the Python language reference.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn