Python Operators and Precedence

Use every kind of Python operator correctly and predict the order an expression is evaluated in.

Lesson 14 of 107Beginner12 min read

Python operators are the symbols and keywords that combine values: + and * for arithmetic, == and < for comparisons, in for membership, is for identity, and/or/not for logic, and &, |, ^, <<, >> for bit manipulation. Operator precedence decides which part of an expression is calculated first when there are no brackets.

Python
print(2 + 3 * 4)      # 14: multiplication binds tighter
print((2 + 3) * 4)    # 20: brackets change the grouping

This lesson groups the operators by purpose, explains the ones that often confuse beginners, such as //, %, is and **, and gives a practical precedence table. The examples come from a print shop calculating quotes.

Arithmetic types

OperatorName17 ? 4-17 ? 4
/true division4.25-4.25
//floor division4-5
%remainder (modulo)13
**power8352183521*

/ always returns a float. // rounds down, towards negative infinity, so -17 // 4 is -5, not -4. % returns the remainder that goes with that floor result, and it takes the sign of the right-hand operand: -17 % 4 is 3 because -5 * 4 + 3 == -17. The rule a == (a // b) * b + a % b always holds.

*(-17) ** 4 is 83521, but -17 ** 4 without brackets is -83521, as explained under precedence below. Mixing int and float gives a float; + and * also work on strings and lists, joining and repeating them.

Comparison and identity

== asks "do these have equal values?" is asks "are these the very same object in memory?"

Python
a = [1, 2]
b = [1, 2]
c = a
print(a == b, a is b)   # True False: equal values, different lists
print(a is c)           # True: two names, one list

Use is for singletons, objects of which only one exists: x is None, x is True. For numbers and strings, always use ==. CPython reuses some small integers and short strings, so is sometimes appears to work for them, but that is an implementation detail that changes between versions and values. Python 3.8 and later even print a SyntaxWarning for x is "text" with a literal.

!= and is not are the negated forms. not x == y is valid but harder to read than x != y.

Membership and bits

in and not in test containment and read like English:

Python
codes = {"A4", "A3", "POSTER"}
print("A4" in codes)              # True
print("ink" in "pink ink")        # True: substring test
prices = {"A4": 0.10, "A3": 0.25}
print(0.10 in prices)             # False: dictionaries test keys
print(0.10 in prices.values())    # True

Membership in sets and dictionaries is fast at any size; in lists and strings Python scans item by item.

Bitwise operators work on the binary digits of integers: & (and), | (or), ^ (exclusive or), ~ (invert), << and >> (shift). They're used for compact flags and permissions:

Python
COLOUR, DOUBLE_SIDED, STAPLED = 1, 2, 4
job = COLOUR | STAPLED            # 5, binary 101
print(bool(job & DOUBLE_SIDED))   # False
print(bool(job & STAPLED))        # True

Don't confuse & with and: & combines bits and always evaluates both sides.

Precedence

From highest (evaluated first) to lowest, the operators you'll use most are:

  1. () brackets
  2. ** power (right-associative)
  3. unary -x, +x, ~x
  4. *, /, //, %
  5. +, -
  6. <<, >>, then &, then ^, then |
  7. comparisons, in, not in, is, is not
  8. not, then and, then or

Operators on the same level are evaluated left to right, except **, which groups from the right: 2 ** 3 ** 2 is 2 ** 9 = 512. Because ** binds tighter than unary minus, -2 ** 2 is -(2 ** 2) = -4, while (-2) ** 2 is 4.

You don't need to memorise the whole table. Remember that arithmetic happens before comparisons, comparisons before not/and/or, and add brackets whenever a reader might hesitate. Brackets cost nothing and prevent bugs.

Independent practice and a worked check

Task: write a quote formula with explicit parentheses and distinguish logical, membership and bitwise operations. Calculate a price of £0.08 per sheet plus a £5 setup fee, with 10% off when the job is over 400 sheets; check the size code is in an allowed set; and test a finishing flag with &.

Python
ALLOWED = {"A4", "A3"}
STAPLED, FOLDED = 1, 2

sheets, size, finish = 444, "A4", STAPLED | FOLDED
base = (sheets * 0.08) + 5
total = base * (0.9 if sheets > 400 else 1)

print(size in ALLOWED and sheets > 0)    # logical + membership
print(bool(finish & FOLDED))             # bitwise flag test
print(round(total, 2))                   # 36.47

For the worked check, 2 + 3 * 4 evaluates to 14, because multiplication has higher precedence than addition.

Reference and next practice

The language reference lists the full operator precedence table. Continue with booleans and expressions for and/or details, and the numbers lesson for rounding. Practise with the Python exercises and Python quiz.

Operators and Precedence Summary

  • Arithmetic types: True division, floor division, remainder and exponentiation have distinct numeric purposes.
  • Comparison and identity: Equality compares values while is compares object identity.
  • Membership and bits: in checks containment while bitwise operators combine integer bit patterns.
  • Precedence: Higher precedence operators group first, and parentheses make the intended grouping clear.

Operators and Precedence Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Operators and Precedence in a small program

Python
print(2 + 3 * 4)
print((2 + 3) * 4)
print(-17 // 4, -17 % 4)
Output
14
20
-5 3
Line-by-line explanation
  1. Line 1* is evaluated before +: 3 * 4 = 12, then 2 + 12.
  2. Line 2The brackets force the addition first: 5 * 4.
  3. Line 3Floor division rounds -4.25 down to -5, and the matching remainder is 3.
Example 2

A print shop quote

Python
pages = 37
copies = 12
price_per_page = 0.08
setup_fee = 5
sheets_per_box = 500

sheets = pages * copies
boxes = -(-sheets // sheets_per_box)      # ceiling division
leftover = boxes * sheets_per_box - sheets
quote = setup_fee + (sheets * price_per_page)

print(sheets, "sheets in", boxes, "boxes,", leftover, "spare")
print(f"Quote: {quote:.2f}")
print("Large job:", sheets > 400 and copies > 10)
Output
444 sheets in 1 boxes, 56 spare
Quote: 40.52
Large job: True
Line-by-line explanation
  1. Line 8Negating, floor-dividing and negating again rounds up: a common idiom for "how many boxes".
  2. Line 10The brackets aren't required, since * binds tighter than +, but they make the intention obvious.
  3. Line 14Both comparisons are evaluated before and combines them.

Common Operators and Precedence Mistakes

Using is to compare values

Don't
size = input("Paper size: ")   # user types A4
if size is "A4":
    print("Standard")          # may not run
Do
size = input("Paper size: ")
if size == "A4":
    print("Standard")

is checks object identity. Two strings with the same characters can be different objects, so use == for values and reserve is for None.

Forgetting that ** binds tighter than unary minus

Don't
print(-3 ** 2)     # -9
Do
print((-3) ** 2)   # 9

Python reads -3 ** 2 as -(3 ** 2). Put the negative number in brackets when it is the base.

Operators and Precedence in Real Projects

Operators in everyday code

Modulo appears constantly in real programs: alternating row colours (i % 2), wrapping a carousel back to the start ((index + 1) % len(slides)), and converting seconds into minutes and seconds. Floor division paginates results (page = item_number // per_page). Membership tests filter input (if extension in {".jpg", ".png"}), and is None checks optional values.

Bitwise flags are common in lower-level code, file permissions (0o644) and libraries such as re, where flags are combined with |: re.IGNORECASE | re.MULTILINE. In pandas and NumPy, & and | combine element-wise conditions, which is why those comparisons need brackets: df[(df.size > 10) & (df.colour == "red")].

Operators and Precedence FAQ

What is the difference between / and // in Python?

/ performs true division and always returns a float: 7 / 2 is 3.5. // performs floor division and rounds down to the nearest whole number: 7 // 2 is 3 and -7 // 2 is -4. With float operands, // returns a float such as 3.0.

What does % do in Python?

For numbers, % gives the remainder after floor division: 17 % 5 is 2. It's used to test divisibility (n % 2 == 0 for even numbers) and to wrap values around a range. For strings, % is also the old-style formatting operator, as in "%s items" % 3.

When should I use is instead of ==?

Use is only to check whether two names refer to the same object, which in practice means comparing with None, True or False, or sentinel objects. Use == for all value comparisons, including numbers and strings.

Does Python have ++ or -- operators?

No. Use count += 1 and count -= 1. Writing ++count is valid but does nothing useful: it applies unary plus twice. count++ is a SyntaxError.

What is the walrus operator := in Python?

Added in Python 3.8, := assigns a value inside an expression and returns it, for example while (line := file.readline()):. It can save a line in loops and comprehensions, but use it sparingly; a separate assignment is often clearer.

Operators and Precedence Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

What does 2 + 3 * 4 evaluate to?

Multiple choicemedium

Which review concern is valid for operators and precedence?

Operators and Precedence Quiz

2 questions to check what you learned.

  1. What does 2 + 3 * 4 evaluate to?

    • 20
    • 14
    • Python ignores the distinction
  2. Which statement correctly describes membership and bits?

    • in checks containment while bitwise operators combine integer bit patterns.
    • Only the example output matters, not the rule
    • Every operation has the same behavior