Why this matters
Calculations are everywhere: totals, averages, unit conversions, positions on a screen, wrapping around a clock. Python's arithmetic looks like school math, but a few operators behave in ways that school math never covered: two kinds of division, a remainder with a sign rule, and an exponent operator that groups right to left. Getting these exactly right, and knowing how Python decides what to compute first, prevents a whole class of quiet wrong-answer bugs that no error message will warn you about.
Expressions, operators, operands
An expression is any piece of code that produces a value: 42, x, x + 1, int(input()) * 2. An operator is a symbol like + that combines operands (the values on either side) into a new value. Python evaluates an expression into a single object; a statement such as total = price * qty then does something with it.
The arithmetic operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | addition | 7 + 2 | 9 |
- | subtraction | 7 - 2 | 5 |
* | multiplication | 7 * 2 | 14 |
/ | true division | 7 / 2 | 3.5 |
// | floor division | 7 // 2 | 3 |
% | modulo (remainder) | 7 % 2 | 1 |
** | exponent (power) | 7 ** 2 | 49 |
-x | negation | -7 | -7 |
True division: /
/ always returns a float, even when the division is exact:
print(10 / 2)
print(7 / 2)
print(type(10 / 2).__name__)
5.0
3.5
float
This was a deliberate change in Python 3 (Python 2's 7 / 2 gave 3). It means / behaves like math division and its result type does not depend on the operand types.
Floor division // and modulo %
a // b divides and rounds down to the nearest whole number (the "floor"). a % b is the remainder that goes with it. They are tied together by an identity that always holds:
(a // b) * b + (a % b) == a
With positive numbers this is the long division you know: 17 divided by 5 is 3 remainder 2.
print(17 // 5, 17 % 5)
print(-17 // 5, -17 % 5)
print(17 // -5, 17 % -5)
print(7.5 // 2, 7.5 % 2)
3 2
-4 3
-4 -3
3.0 1.5
With negatives, "round down" means toward negative infinity: -17 / 5 is -3.4, and the floor of -3.4 is -4. The remainder then follows from the identity: -4 * 5 + 3 = -17. In Python the result of % always has the same sign as the divisor (or is zero). That is what you want for wrap-around arithmetic:
hour = 2
print((hour - 5) % 24) # 5 hours before 2 o'clock
21
C, Java and JavaScript truncate toward zero instead, so -17 / 5 is -3 and -17 % 5 is -2 there. If you port code between languages, this difference matters.
Common uses of %: testing divisibility (n % 2 == 0 means even), extracting the last digit (n % 10), and wrapping indexes around ((i + 1) % length).
divmod
divmod(a, b) returns both results at once as a pair, which you can unpack into two names:
minutes, seconds = divmod(200, 60)
print(minutes, seconds)
3 20
divmod(200, 60) is the tuple (3, 20); the assignment binds minutes to 3 and seconds to 20. (Tuples and unpacking get a full treatment in module 7.)
Exponent **
print(2 ** 10)
print(2 ** -2)
print(9 ** 0.5) # square root
print(8 ** (1 / 3)) # cube root, approximately
1024
0.25
3.0
2.0
Int to a non-negative int power stays an exact int; a negative or fractional exponent gives a float. pow(base, exp, mod) with three arguments computes (base ** exp) % mod efficiently, which cryptography relies on.
Precedence: what is computed first
When an expression has several operators, precedence decides which binds more tightly. From highest to lowest, for the arithmetic operators:
| Precedence | Operators | Grouping |
|---|---|---|
| highest | ( ... ) parentheses | |
** | right to left | |
unary -x, +x | ||
*, /, //, % | left to right | |
| lowest (of these) | +, - | left to right |
Comparisons (<, ==, ...) and then not, and, or come below all of these; the next lesson covers them.
print(2 + 3 * 4) # * before +
print((2 + 3) * 4)
print(2 * 3 ** 2) # ** before *
14
20
18
Associativity decides the order among operators of equal precedence. Most group left to right:
print(100 / 10 / 5) # (100 / 10) / 5
print(10 - 4 - 3) # (10 - 4) - 3
2.0
3
But ** groups right to left, as in math notation, and binds more tightly than a unary minus on its left:
print(2 ** 3 ** 2) # 2 ** (3 ** 2) = 2 ** 9
print(-2 ** 2) # -(2 ** 2)
print((-2) ** 2)
512
-4
4
Underneath, precedence is decided entirely at compile time. The parser builds a syntax tree in which tightly binding operators are deeper, and the compiler emits bytecode that evaluates the deepest parts first. You saw this with dis in module 1: for a + b * c the * instruction comes before the +.
Note: When in doubt, add parentheses. They cost nothing at run time and make intent obvious to the reader.
(a * b) + cis clearer than relying on everyone remembering the table.
A worked example
Converting a temperature, averaging, and a percentage, with deliberate parentheses:
celsius = 37
fahrenheit = celsius * 9 / 5 + 32
scores_total = 85 + 92 + 78
average = scores_total / 3
passed, total = 18, 24
percent = passed / total * 100
print(fahrenheit, average, percent)
98.6 85.0 75.0
celsius * 9 / 5 + 32 works without parentheses because * and / group left to right and + comes last. Writing (celsius * 9 / 5) + 32 would be clearer still.
Common mistakes
- Dividing by a product without parentheses.
x / 2 * ais(x / 2) * a. Writex / (2 * a). - Averaging without grouping.
a + b / 2isa + (b / 2). Write(a + b) / 2. - Negative bases.
-2 ** 2is -4. Parenthesize:(-2) ** 2. - Expecting C-style results for negatives.
-7 // 2is -4 and-7 % 2is 1 in Python. - Division by zero.
x / 0,x // 0andx % 0all raiseZeroDivisionError: division by zero(orinteger modulo by zero). Python never returns infinity for these. - Writing
^for power.2 ^ 3is 1:^is bitwise XOR (lesson 4 of this module). Power is**.
Recap
/always gives a float;//floors (rounds toward negative infinity);%gives the matching remainder with the sign of the divisor.(a // b) * b + a % b == aalways holds.divmod(a, b)gives both at once.**is exponent: right-associative and tighter than unary minus.- Precedence: parentheses,
**, unary minus,* / // %, then+ -; equal precedence groups left to right except**. - Precedence is resolved at compile time; parentheses make your intent explicit.
Going further: the full precedence table is in the Python Language Reference, section "Operator precedence". Try import ast; print(ast.dump(ast.parse("-2 ** 2", mode="eval"), indent=2)) to see how the tree groups it.