Python Operators Explained: Arithmetic, Comparison, Logical, and the Tricky Ones
Python operators do exactly what the name suggests — they operate on values. You already know the arithmetic ones from school. The interesting parts are the Python-specific operators, the precedence rules that determine which operations happen first, and the few operators that behave differently than you might expect.
Arithmetic Operators
The standard math operators:
a, b = 17, 5
print(a + b) # 22 — additionprint(a - b) # 12 — subtractionprint(a * b) # 85 — multiplicationprint(a / b) # 3.4 — true division (always returns float)print(a // b) # 3 — floor division (rounds down, returns int)print(a % b) # 2 — modulo (remainder)print(a ** b) # 1419857 — exponentiationTwo things worth noting:
Division always returns a float. 10 / 2 gives 5.0, not 5. Use // when you need an integer result.
Floor division rounds toward negative infinity, not toward zero. This matters with negative numbers:
print(-17 // 5) # -4, not -3print(-17 % 5) # 3, not -2If you need truncation toward zero, use int(-17 / 5) instead.
Comparison Operators
These return True or False:
x = 10
print(x == 10) # True — equal toprint(x != 5) # True — not equal toprint(x > 8) # True — greater thanprint(x < 8) # False — less thanprint(x >= 10) # True — greater than or equal toprint(x <= 9) # False — less than or equal toPython allows chaining comparisons, which reads more naturally:
score = 75
# Instead of: score >= 60 and score < 90if 60 <= score < 90: print("Passing grade")Important: use == for equality, = for assignment. Using = in a condition causes a SyntaxError in Python (unlike some languages where it silently assigns).
Identity and Membership Operators
Two categories that beginners sometimes overlook:
Identity operators: is and is not
These test whether two variables point to the same object in memory — not whether they have equal values:
a = [1, 2, 3]b = [1, 2, 3]c = a
print(a == b) # True — same valuesprint(a is b) # False — different objectsprint(a is c) # True — same object
# Use 'is' for None comparisonsvalue = Noneif value is None: print("No value set")Always use is None, not == None. The is check is more accurate and is the Python convention.
Membership operators: in and not in
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # Trueprint("grape" not in fruits) # True
# Works on strings, lists, tuples, sets, and dictstext = "Hello, world"print("world" in text) # True
config = {"debug": True, "port": 8080}print("debug" in config) # True — checks keysLogical Operators
and, or, and not combine boolean expressions:
age = 25has_ticket = True
# and: both must be Trueif age >= 18 and has_ticket: print("Entry allowed")
# or: at least one must be Trueif age < 13 or age > 65: print("Discount available")
# not: reverses the resultif not has_ticket: print("No ticket found")Short-circuit evaluation
Python stops evaluating as soon as the result is determined. With and, if the first expression is False, the second is never evaluated. With or, if the first is True, the second is skipped:
def expensive_check(): print("Running expensive check...") return True
# The second expression is never evaluatedresult = False and expensive_check() # prints nothing
# Practical use: safe attribute accessuser = Nonename = user and user.name # name = None without AttributeErrorTruthy and falsy values
Logical operators work on any value, not just booleans. Empty sequences, zero, None, and False are all falsy:
name = ""display_name = name or "Anonymous" # "Anonymous" — because "" is falsyprint(display_name)
items = []if not items: print("Cart is empty")Assignment Operators
Beyond the basic =, Python has compound assignment operators:
count = 10count += 3 # count = count + 3 = 13count -= 2 # 11count *= 2 # 22count //= 4 # 5count **= 2 # 25The walrus operator := (Python 3.8+)
The walrus operator assigns a value and returns it in the same expression. It’s most useful in while loops and comprehensions where you’d otherwise need to compute something twice:
# Without walrus — compute len(line) twicewhile len(line := input("Enter line: ")) > 0: print(f"You entered {len(line)} characters")
# More useful example: filtering with a computed valuedata = [1, 5, 2, 8, 3, 9]filtered = [y for x in data if (y := x * 2) > 10]print(filtered) # [16, 18]Operator Precedence
When multiple operators appear in one expression, precedence determines the order of evaluation (highest to lowest):
**(exponentiation)+x,-x,~x(unary)*,/,//,%+,-<<,>>(bitwise shifts)&(bitwise AND)^(bitwise XOR)|(bitwise OR)- Comparison operators:
==,!=,<,>,<=,>=,is,in notandor
When in doubt, use parentheses. (a + b) * c is clearer than relying on the reader to recall precedence. The only rule worth memorising: multiplication before addition, and not before and before or.
# Surprising without knowledge of precedenceprint(not True or True) # True — (not True) or Trueprint(not (True or True)) # False — not (True)Parentheses resolve any ambiguity and make intent explicit.