Operators & Expressions
2612 words
13 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Operators & Expressions > **Why read this?** An expression is how you compute new values from existing ones. Every calculator, every formula, every decision your program makes involves operators.

Operators & Expressions
Why read this? An expression is how you compute new values from existing ones. Every calculator, every formula, every decision your program makes involves operators. Mastering operators is like learning the verbs of the Python language — they're how you make things happen.
🎯 Learning Objectives
By the end of this topic, you will be able to:
- Use all arithmetic, comparison, logical, and membership operators
- Predict expression evaluation using precedence and associativity rules
- Distinguish between
==(value equality) andis(identity) - Write boolean expressions with
and,or,not - Use
into check membership in collections
📋 Prerequisites
- Variables & Data Types — You need to understand variables and types.
- Input, Output & Formatted Strings — Useful but not essential.
📖 Core Content
4.1 What Is an Expression?
Intuition: An expression is any piece of code that produces a value.
2 + 3 is an expression (it produces 5). "Hello" + " " + "World" is an expression (it produces "Hello World"). Even a single variable like name is an expression (it produces the value stored in it).pseudoExpression → Python evaluates it → Value 2 + 3 → 5 "A" + "B" → "AB" len("hi") → 2
4.2 Arithmetic Operators — Review and Extend
| Operator | Name | Example | Result | Notes |
|---|---|---|---|---|
+ | Addition | 5 + 3 | 8 | Also works on strings (concatenation) |
- | Subtraction | 5 - 3 | 2 | Also negation: -x |
* | Multiplication | 5 * 3 | 15 | Also string repetition: "Hi" * 3 → "HiHiHi" |
/ | Division | 5 / 3 | 1.666... | Always returns float |
// | Floor division | 5 // 3 | 1 | Rounds DOWN, not toward zero |
% | Modulus | 5 % 3 | 2 | Remainder after division |
** | Exponentiation | 5 ** 3 | 125 | 5 to the power 3 |
Important nuance about
// with negative numbers:python# runnable print(7 // 3) # 2 (2*3=6, remainder 1) print(-7 // 3) # -3 (-3*3=-9, remainder 2) ← NOT -2! print(7 // -3) # -3 print(-7 // -3) # 2
Output:
pseudo2 -3 -3 2
Why? Floor division always rounds DOWN (toward negative infinity), not toward zero.
-7/3 = -2.333..., and the floor (round down) of -2.333 is -3, not -2.4.3 Comparison Operators — Making Decisions
Comparison operators compare two values and return a boolean (
True or False).python# runnable a = 10 b = 5 print(a == b) # False (equal to) print(a != b) # True (not equal to) print(a > b) # True (greater than) print(a < b) # False (less than) print(a >= b) # True (greater than or equal) print(a <= b) # False (less than or equal)
Output:
pseudoFalse True True False True False
⚠️ Critical:=is ASSIGNMENT (store a value).==is COMPARISON (check if equal). This is the #1 mistake beginners make!
4.4 Chained Comparisons
Python allows you to chain comparisons naturally:
python# runnable x = 15 print(10 < x < 20) # True (10 < 15 and 15 < 20) print(10 < x < 12) # False (15 is not < 12) # Equivalent to: print(10 < x and x < 20) # True
Output:
pseudoTrue False True
This works for any comparison:
a <= b < c > d etc. Python evaluates each pair separately and combines them with and.4.5 Logical Operators — and, or, not
Logical operators combine multiple boolean values.
python# runnable age = 22 has_license = True # and: both must be True print(age >= 18 and has_license) # True (both conditions are True) # or: at least one must be True has_car = False print(has_license or has_car) # True (has_license is True) # not: reverses the boolean is_weekend = False print(not is_weekend) # True
Output:
pseudoTrue True True
Diagram
Rendering diagram
4.6 Short-Circuit Evaluation
Python is lazy — it stops evaluating a logical expression as soon as it knows the answer.
python# runnable def get_true(): print("get_true called") return True def get_false(): print("get_false called") return False # Short-circuit with and: if first is False, second is NOT evaluated print(get_false() and get_true()) # get_true is NEVER called! print("---") # Short-circuit with or: if first is True, second is NOT evaluated print(get_true() or get_false()) # get_false is NEVER called!
Output:
pseudoget_false called False --- get_true called True
Why this matters: If the second operand has side effects (like modifying a variable), those side effects won't happen if short-circuiting kicks in. Also, you can use this to safely check conditions:
if x != 0 and 10/x > 2 — if x is 0, the division never happens, avoiding ZeroDivisionError.4.7 Membership Operators — in and not in
What problem does this solve? You often need to check if something exists inside a collection — like checking if a letter is in a word, or if an item is in a list.
python# runnable word = "python" print("p" in word) # True print("z" in word) # False print("tho" in word) # True (substring exists) print("xyz" not in word) # True (xyz is NOT in word) # Works with lists too fruits = ["apple", "banana", "cherry"] print("banana" in fruits) # True print("grape" in fruits) # False
Output:
pseudoTrue False True True True False
4.8 Identity Operators — is and is not
Crucial difference:
== checks if values are the same. is checks if two variables point to the SAME object in memory.python# runnable a = [1, 2, 3] b = [1, 2, 3] # b has the same values as a c = a # c points to the SAME list as a print(a == b) # True (values are equal) print(a is b) # False (different objects in memory) print(a is c) # True (same object) # For simple types like small integers, Python sometimes reuses objects x = 5 y = 5 print(x is y) # True (Python caches small integers)
Output:
pseudoTrue False True True
⚠️ Rule of thumb: Use==for comparing values. Useisfor checkingNone(if x is None:). Never useisto compare numbers or strings in normal code — it behaves unpredictably across implementations.
4.9 Operator Precedence — The Complete Table
When multiple operators appear in an expression, Python follows this order (highest to lowest precedence):
| Level | Operators | Description |
|---|---|---|
| 1 | (...) | Parentheses (highest) |
| 2 | ** | Exponentiation |
| 3 | +x, -x, ~x | Unary plus, minus, bitwise NOT |
| 4 | *, /, //, % | Multiplication, division, floor division, modulus |
| 5 | +, - | Addition, subtraction |
| 6 | > | Bitwise shifts |
| 7 | & | Bitwise AND |
| 8 | ^ | Bitwise XOR |
| 9 | | | Bitwise OR |
| 10 | ==, !=, >, =, <=, in, not in, is, is not | Comparisons, membership, identity |
| 11 | not | Logical NOT |
| 12 | and | Logical AND |
| 13 | or | Logical OR (lowest) |
Associativity: When operators have the SAME precedence, associativity decides the order:
- Left-to-right: Most operators (
+,-,*,/,//,%,and,or, etc.) - Right-to-left:
**(exponentiation) and assignment operators
4.10 Worked Example 1: Complex Expression Evaluation
python# runnable result = 5 + 3 * 2 ** 2 // 4 - 1 print(result)
Step-by-step evaluation:
2 ** 2→4(exponent: highest of the actual operators)3 * 4 // 4→12 // 4→3(* and // same precedence, left to right)5 + 3 - 1→7Output:7
4.11 Worked Example 2: Logical Expression with Comparisons
python# runnable x = 10 y = 20 z = 15 result = x < y and y > z or not x == z print(result)
Step-by-step:
x < y→10 < 20→Truey > z→20 > 15→Truex == z→10 == 15→Falsenot False→TrueTrue and True→TrueTrue or True→TrueOutput:True
4.12 Worked Example 3: Leap Year Condition
A year is a leap year if it's divisible by 400, OR divisible by 4 but NOT by 100.
python# runnable year = 2024 is_leap = (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0) print(f"{year} is a leap year? {is_leap}") year = 1900 is_leap = (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0) print(f"{year} is a leap year? {is_leap}") year = 2000 is_leap = (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0) print(f"{year} is a leap year? {is_leap}")
Output:
pseudo2024 is a leap year? True 1900 is a leap year? False 2000 is a leap year? True
4.13 Worked Example 4: Safe Division with Short-Circuit
python# runnable def divide_safe(a, b): # Short-circuit: if b == 0, the division never happens return b != 0 and a / b print(divide_safe(10, 2)) # 5.0 print(divide_safe(10, 0)) # False (b != 0 is False, so a/b never runs)
Output:
pseudo5.0 False
Note: In real code, you'd useif/elsefor safety. This example demonstrates short-circuit behavior.
4.14 Worked Example 5: Combining All Operator Types
python# runnable age = 25 salary = 50000 has_job = True credit_score = 720 # Loan eligibility: age >= 21, salary > 30000, has job, good credit eligible = age >= 21 and salary > 30000 and has_job and credit_score >= 650 print(f"Loan eligible: {eligible}") # Also check if they're in a "premium" category premium = salary > 100000 or (salary > 50000 and credit_score > 750) print(f"Premium customer: {premium}") # Not a risky candidate risky = not has_job or credit_score < 600 print(f"Risky: {risky}")
Output:
pseudoLoan eligible: True Premium customer: False Risky: False
📐 Key Concepts Reference
| Operator | Type | Description | Example | Result |
|---|---|---|---|---|
+ | Arithmetic | Addition | 5 + 3 | 8 |
- | Arithmetic | Subtraction | 5 - 3 | 2 |
* | Arithmetic | Multiplication | 5 * 3 | 15 |
/ | Arithmetic | Float division | 5 / 3 | 1.666... |
// | Arithmetic | Floor division | 5 // 3 | 1 |
% | Arithmetic | Modulus | 5 % 3 | 2 |
** | Arithmetic | Exponentiation | 5 ** 3 | 125 |
== | Comparison | Equal to | 5 == 3 | False |
!= | Comparison | Not equal to | 5 != 3 | True |
> | Comparison | Greater than | 5 > 3 | True |
< | Comparison | Less than | 5 < 3 | False |
>= | Comparison | Greater or equal | 5 >= 3 | True |
<= | Comparison | Less or equal | 5 <= 3 | False |
and | Logical | Both True | True and False | False |
or | Logical | Either True | True or False | True |
not | Logical | Negate | not True | False |
in | Membership | Is member of | "a" in "cat" | True |
is | Identity | Same object | x is None | True/False |
⚠️ Common Pitfalls
Pitfall 1: Confusing = with ==
The mistake:
if x = 5: instead of if x == 5: The error: SyntaxError: invalid syntax. Maybe you meant '=='? Why: Single = is assignment (a statement), not a comparison (an expression). Fix: Use == for comparisons. Remember: "checking equality uses two equals."Pitfall 2: and/or Return Values (Not Boolean)
The mistake: Thinking
and/or always return True/False. The truth: and and or return the value of one of the operands, not necessarily a boolean.pythonprint(0 and 5) # 0 (falsy value returned) print(3 and 5) # 5 (last truthy value) print(0 or 5) # 5 (first truthy value) print(3 or 5) # 3 (first truthy value)
Fix: If you need a boolean, use
bool() or compare: if bool(x and y):Pitfall 3: Floating-Point Equality
The mistake:
0.1 + 0.2 == 0.3 The result: False (surprise!) Why: Floating-point numbers can't represent some decimals exactly in binary.pythonprint(0.1 + 0.2) # 0.30000000000000004 print(0.1 + 0.2 == 0.3) # False
Fix: Use
abs((0.1 + 0.2) - 0.3) < 1e-10 (check if difference is tiny).Pitfall 4: is for Value Comparison
The mistake:
if x is 1000: when you want if x == 1000: Why: Python may or may not reuse objects for large integers. It works sometimes, fails other times. Fix: Always use == for comparing values. Use is only for None, True, False.📝 Practice Questions
Q1: Evaluate step-by-step: 10 + 2 * 3 ** 2 - 6 // 4Answer:pseudo10 + 2 * 3 ** 2 - 6 // 4 = 10 + 2 * 9 - 6 // 4 (exponent: 3**2 = 9) = 10 + 18 - 6 // 4 (multiply: 2*9 = 18) = 10 + 18 - 1 (floor division: 6//4 = 1) = 27Q2: What's the output?pythonprint(5 > 3 and 2 < 4 or not 7 == 7)Answer:pseudoTrueStep-by-step:
5 > 3→True2 < 4→TrueTrue and True→True7 == 7→Truenot True→FalseTrue or False→TrueQ3: What's the difference between print(10 / 3) and print(10 // 3)?Answer:
10 / 3→3.3333333333333335(float division, precise)10 // 3→3(floor division, rounds down)/always returns float.//returns int when both operands are int (but float if either is float). Q4: What does this code output and why?pythonprint("a" in "apple") print("app" in "apple") print("x" not in "apple")Answer:pseudoTrue True True
"a"is a character in"apple"→ True"app"is a substring of"apple"→ True"x"is NOT in"apple"→not inreturns True Q5: Fix the error in this code:pythonx = input("Number: ") if x % 2 == 0: print("Even")Answer: Error:TypeError: not all arguments converted during string formattingor similar. Fix: Convert input to int:x = int(input("Number: "))input()returns a string. The%operator on strings does something different (formatting). Q6: What does -7 // 3 evaluate to? Why?Answer:-7 // 3→-3Because floor division rounds DOWN to negative infinity.-7/3 = -2.333.... Rounding down gives-3(more negative). Not-2(which would be rounding toward zero). Q7: Write a condition that checks if a number n is between 1 and 100 (inclusive).Answer:python# runnable n = 50 if 1 <= n <= 100: print(f"{n} is between 1 and 100")Or:if n >= 1 and n <= 100:Q8: What does this output?pythonprint(False or True and False)Answer:pseudoFalse
True and False→False(and has higher precedence than or)False or False→FalseQ9: Write a program that checks if a character entered by the user is a vowel.Answer:python# runnable ch = input("Enter a letter: ").lower() is_vowel = ch in "aeiou" print(f"Is '{ch}' a vowel? {is_vowel}")Q10: What's the value of this expression?python(15 % 4) == 3 and (2 ** 3) > 10 or "py" in "python"Answer:pseudoTrueStep-by-step:
15 % 4→33 == 3→True2 ** 3→88 > 10→FalseTrue and False→False"py" in "python"→TrueFalse or True→True
🔗 Cross-References
- Next Topic: Strings — Basics & Operations
- Previous Topic: Input, Output & Formatted Strings
- BSCS1001 Computational Thinking: Boolean logic (and/or/not) is the foundation of decision-making in algorithms.
- BSCS2002 PDSA: Bitwise operators (
&,|,<<,>>) become important for low-level data structures. - Reference: Python for Everybody, Chapter 2 (Sections 2.5-2.8)
- Video: L9: Operators & expressions part 1, L10: Operators & expressions part 2 Join Discord Previous3. Input & OutputNext5. Strings Basics