Skip to main content

Expressions and Operators

Topic — An expression is any valid combination of values, variables, and operators that Python evaluates to produce a result. While arithmetic symbols look familiar from primary school mathematics, Python's runtime introduces critical computational nuances: division (/) always returns a float, floor division (//) rounds toward negative infinity, and exponentiation (**) evaluates right-to-left. This guide details operator mechanics, order of operations, and five ways to structure the same calculation.


1. The Core Concept​

Python divides arithmetic into seven core operations:

OperatorMathematical NameExpressionResultReturn TypeOperational Behavior
+Addition15 + 2540intSum of operands
-Subtraction30 - 1020intDifference of operands
*Multiplication10 * 660intProduct / repeated scaling
/True Division30 / 56.0floatAlways produces a float, even on exact division
//Floor Division23 // 54intRounds toward negative infinity
%Modulo25 % 41intRemainder of division
**Exponentiation2 ** 532intPower / repeated multiplication
tip

If you only take one thing from this page

In Python 3, single slash / is True Division and always returns a float (10 / 2 evaluates to 5.0, not 5). Double slash // is Floor Division and rounds down toward −∞-\infty. Exponentiation ** evaluates right-to-left (2 ** 3 ** 2 == 512, not 6464).


2. Interactive Operator & Precedence Sandbox​

Select an expression below to inspect its step-by-step evaluation order, type resolution, and mathematical nuances live:

Interactive Operator and Precedence Sandbox

Select an expression to inspect its AST execution trace and mathematical quirks:

Evaluated Python Expression
2 ** 3 ** 2
Result: 512int
Step-by-Step Execution Trace
1. Right-to-left associativity: evaluate 3 ** 2 first = 9
2. Evaluate 2 ** 9 = 512
Computational Insight: Unlike all other binary operators that evaluate left-to-right, ** evaluates right-to-left! (2**3)**2 is 64, but 2**3**2 is 512.

3. Order of Precedence (PEMDAS Hierarchy)​

When an expression contains multiple operators, Python resolves them according to a strict binding hierarchy:

LevelOperator CategoryOperatorsAssociativity
1 (Highest)Parentheses( )Innermost first
2Exponentiation**Right-to-Left
3Unary signs+x, -x, ~xRight-to-Left
4Multiplicative*, /, //, %Left-to-Right
5Additive+, -Left-to-Right
6Bitwise Shifts<<, >>Left-to-Right
7Bitwise AND / OR&, ^, |Left-to-Right
8Comparisons & Identity==, !=, <, <=, >, >=, is, inChained
9Boolean NOTnotRight-to-Left
10Boolean ANDandLeft-to-Right
11 (Lowest)Boolean ORorLeft-to-Right
info

The Exponentiation Associativity Exception

Every binary arithmetic operator (+, -, *, /, //, %) is left-associative (a−b−ca - b - c is evaluated as (a−b)−c(a - b) - c).

The only exception is ** (Exponentiation), which is right-associative:

232=2(32)=29=5122^{3^2} = 2^{(3^2)} = 2^9 = 512

If you intend (23)2=82=64(2^3)^2 = 8^2 = 64, you must explicitly add parentheses: (2 ** 3) ** 2.


4. Five Ways to Structure the Same Calculation​

Consider calculating the average of three exam scores (85,90,9285, 90, 92):


# Parentheses strictly required to prevent / from dividing only 92!
average = (85 + 90 + 92) / 3
print(f"Average: {average:.2f}") # 89.00
  • Pros: Compact one-liner.
  • Cons: Hardcoded values; not reusable.

5. Implementation Lab​

tip

Lab Exercise: Expressions, Operators & Precedence Tracing

An interactive, fully functional Google Colab / Jupyter Notebook is available to evaluate the 5 foundational arithmetic operations, examine negative floor division quirks, verify right-to-left power associativity, and test string repetition live in your browser.

Open In Colab

How to run the lab:

  1. Click the "Open In Colab" badge above to launch the interactive notebook.
  2. Run cells sequentially to benchmark operator precedence and string casting errors.

Key Experiments to Run:

  • Experiment 1 (The Strict Float Rule): Confirm that 30 / 5 returns float 6.0, while 30 // 5 returns integer 6.
  • Experiment 2 (Negative Floor Division): Compare 23 // 5 (44) against -23 // 5 (−5-5) to observe floor rounding toward negative infinity.
  • Experiment 3 (Exponentiation Associativity): Empirically verify 2 ** 3 ** 2 == 512 vs. (2 ** 3) ** 2 == 64.

6. Common Mistakes​


  • The Misconception: "Writing a + b + c / 3 computes the average of three numbers."
  • Wrong Thinking: Assuming addition happens left-to-right before division.
  • The Right Principle: Division / has higher precedence than addition. Python evaluates a + b + (c / 3). You must wrap the sum in parentheses: (a + b + c) / 3.

7. Summary​

Operator Mechanics

  • True Division (/): Always produces float (10/2 == 5.0).
  • Floor Division (//): Rounds toward −∞-\infty (-23//5 == -5).
  • Modulo (%): Remainder; matches sign of divisor.
  • Exponentiation (**): Right-to-left associativity (2**3**2 == 512).

Precedence Best Practices

  • PEMDAS: (), **, unary, * / // %, + -, comparisons, not, and, or.
  • Parentheses are Free: Use parentheses whenever precedence is not immediately obvious to human readers.
  • String Overloading: + concatenates strings; * repeats sequences.
  • Pairing // and %: Splitting quantities into units and leftovers (mins // 60 and mins % 60).

info

Key Takeaways

  • Division is always float: In Python 3, single slash / will never return an int.
  • Negative floor rounds down: Remember that // floors toward −∞-\infty, meaning -10 // 3 == -4.
  • Right-to-left power: Exponentiation ** evaluates right-to-left; always add parentheses if in doubt.

Next Section: F-Strings - mastering Python 3.6+ formatted string literals, alignment padding, and precision specifiers.


8. Active Recall​

Test your understanding by answering first, then clicking to reveal the underlying principles.

Interactive Checkpoint Quiz​

Interactive Checkpoint: The Right-Associative Exponentiation Trap

What is the evaluated output of the Python expression 2 ** 3 ** 2?

Review Flashcards​

1. [THEORY] Why does Python evaluate -10 // 3 as -4 rather than -3?

  • Floor Function Definition: In mathematics and Python, floor division is defined by the mathematical floor operator: ⌊x⌋=max⁡{m∈Z∣m≤x}\lfloor x \rfloor = \max \{ m \in \mathbb{Z} \mid m \le x \}
  • Exact quotient: −10/3=−3.3333…-10 / 3 = -3.3333\dots
  • The largest integer less than or equal to −3.3333…-3.3333\dots is -4.
  • Many languages (C/Java) truncate toward zero (yielding -3), but Python strictly floors toward negative infinity.
2. [MATH] What is the exact output of print(2 + 3 * 4 ** 2 - 6 / 3)? Trace step by step.

  1. Exponentiation: 42=164^2 = 16. Expression becomes: 2+3×16−6/32 + 3 \times 16 - 6 / 3.
  2. Multiplication & Division:
    • 3×16=483 \times 16 = 48
    • 6/3=2.06 / 3 = 2.0 (Division produces float!)
    • Expression becomes: 2+48−2.02 + 48 - 2.0.
  3. Addition & Subtraction (Left-to-Right):
    • 2+48=502 + 48 = 50
    • 50−2.0=48.050 - 2.0 = \mathbf{48.0} (Float due to division operand).
3. [PRACTICE] How do you convert 127 minutes into hours and remaining minutes in two lines of code?

total_minutes = 127
hours = total_minutes // 60 # 2 hours (whole units)
minutes = total_minutes % 60 # 7 minutes (remainder)
print(f"{hours}h {minutes}m") # 2h 7m
  • Alternatively, use Python's built-in divmod:
hours, minutes = divmod(127, 60) # (2, 7)
4. [ANALYZE] What happens when evaluating 5 > 3 and 2 > 4 or not False? Trace precedence.

  1. Relational Comparisons:
    • 5 > 3   ⟹  True\implies \text{True}
    • 2 > 4   ⟹  False\implies \text{False}
    • Expression: True and False or not False.
  2. Boolean not: not False   ⟹  True\implies \text{True}.
    • Expression: True and False or True.
  3. Boolean and: True and False   ⟹  False\implies \text{False}.
    • Expression: False or True.
  4. Boolean or: False or True   ⟹  True\implies \mathbf{\text{True}}.
5. [THEORY] What is the difference between = (assignment), == (equality), and is (identity)?

  • = Assignment: Binds a variable name to an object on the heap (x = [1, 2]).
  • == Equality: Checks whether two objects hold the same values/contents ([1, 2] == [1, 2] is True).
  • is Identity: Checks whether two variables reference the exact same object at the same memory address ([1, 2] is [1, 2] is False).