Python Operators Explained — Types, Examples and Common Mistakes
Every program you'll ever write comes down to one thing: making decisions with data. Should this user get a discount? Is this password long enough? How much tax does this order cost? Every single one of those questions is answered using operators. They're the verbs of Python — they make things happen. If variables are the nouns (storing data), operators are what bring that data to life.
Before operators existed as a concept, you'd have to write entire custom functions just to add two numbers or check if one value was greater than another. Operators are shorthand that Python (and every other language) gives you so you can express complex logic in a single, readable character or symbol. They solve the problem of 'how do I actually DO something with my data?'
By the end of this article, you'll be able to use all seven categories of Python operators with confidence — arithmetic, comparison, logical, assignment, identity, membership, and bitwise. You'll know not just how to write them but WHY each one exists and when to reach for it. You'll also know the traps that catch beginners (and sometimes experienced devs), so you can sidestep them from day one.
Arithmetic Operators — Python as Your Calculator
Arithmetic operators are the ones you already know from maths class — addition, subtraction, multiplication, and division. But Python adds a few extras that are genuinely useful in real programming: floor division, modulus, and exponentiation.
Floor division (//) divides two numbers and throws away the decimal, giving you only the whole number part. Think of splitting a pizza: if 7 people share a pizza cut into 2, each person gets 3 slices — the remaining 1 slice doesn't magically split. That leftover is exactly what the modulus operator (%) gives you.
The modulus operator is one of the most underrated tools in programming. It's how you check if a number is even or odd, how you build cycling patterns, and how you keep a counter wrapping around a fixed range. The exponent operator () raises a number to a power — so 2 8 gives you 256, which matters a lot in computing, cryptography, and data sizing.
These seven arithmetic operators cover almost every mathematical operation you'll need in everyday Python programming.
# ─── Arithmetic Operators in Python ─────────────────────────────────────── # Let's use a real-world scenario: calculating an order total at a bakery. items_ordered = 7 # Number of croissants ordered price_per_item = 3.50 # Price in dollars # Addition: total cost before any extras subtotal = items_ordered + 2.00 # Adding a $2 bag fee print("Subtotal with bag fee:", subtotal) # 9.5 # Subtraction: applying a discount discount = 1.50 price_after_discount = subtotal - discount print("After discount:", price_after_discount) # 8.0 # Multiplication: total cost for the original order total_cost = items_ordered * price_per_item print("Total cost:", total_cost) # 24.5 # Division: splitting the bill evenly among friends num_friends = 2 cost_per_person = total_cost / num_friends print("Cost per person:", cost_per_person) # 12.25 # Floor Division: how many whole boxes of 3 can we fill? boxes_of_three = items_ordered // 3 print("Full boxes of 3:", boxes_of_three) # 2 (7 // 3 = 2, ignores remainder) # Modulus: how many croissants are left over after boxing? leftover_croissants = items_ordered % 3 print("Leftover croissants:", leftover_croissants) # 1 (7 % 3 = 1) # Exponentiation: calculate 2 to the power of 8 (useful in computing) byte_combinations = 2 ** 8 print("Possible values in one byte:", byte_combinations) # 256
After discount: 8.0
Total cost: 24.5
Cost per person: 12.25
Full boxes of 3: 2
Leftover croissants: 1
Possible values in one byte: 256
Comparison and Logical Operators — Teaching Python to Make Decisions
Comparison operators answer a yes-or-no question about your data. Is this value bigger than that one? Are these two values equal? Python evaluates the comparison and hands you back a boolean — either True or False. That True or False is then used by if-statements, while-loops, and everywhere else decisions are made.
There are six comparison operators: equal (==), not equal (!=), greater than (>), less than (<), greater than or equal to (>=), and less than or equal to (<=). Notice that equality uses TWO equals signs (==). One equals sign (=) is assignment — it stores a value. Two equals signs (==) is comparison — it asks a question.
Logical operators — and, or, not — let you combine multiple comparisons into a single, more powerful condition. Think of them like the connectors in everyday language. 'I'll go to the party IF it's on Saturday AND I'm not working.' That AND is exactly what Python's and operator does: both conditions must be True for the whole thing to be True.
or means at least one condition must be True. not flips a boolean — True becomes False and False becomes True. Together, these six comparison operators and three logical operators are the backbone of every conditional statement you'll ever write.
# ─── Comparison and Logical Operators ───────────────────────────────────── # Scenario: A simple age-gate for a website with a premium tier. user_age = 22 user_is_subscriber = True minimum_age = 18 subscription_price = 9.99 account_balance = 15.00 # ── Comparison Operators ────────────────────────────────────────────────── # == checks equality (note: NOT a single = which would assign a value) print(user_age == 22) # True — age IS 22 print(user_age == 30) # False — age is NOT 30 # != checks inequality print(user_age != 30) # True — 22 is not 30 # > and < check magnitude print(user_age > minimum_age) # True — 22 is greater than 18 print(user_age < minimum_age) # False — 22 is not less than 18 # >= and <= include the boundary value print(user_age >= 22) # True — 22 is equal to 22, so >= is satisfied print(user_age <= 21) # False — 22 is not less than or equal to 21 # ── Logical Operators ───────────────────────────────────────────────────── # AND: BOTH conditions must be True can_access_premium = user_age >= minimum_age and user_is_subscriber print("Can access premium:", can_access_premium) # True (22>=18 AND subscriber) # OR: AT LEAST ONE condition must be True can_afford_subscription = account_balance >= subscription_price or user_is_subscriber print("Can afford subscription:", can_afford_subscription) # True # NOT: flips the boolean — True becomes False, False becomes True print("Is a guest user:", not user_is_subscriber) # False (they ARE a subscriber) # Combining all three for a real access check user_is_banned = False full_access = (user_age >= minimum_age) and user_is_subscriber and (not user_is_banned) print("Full access granted:", full_access) # True
False
True
True
False
True
False
Can access premium: True
Can afford subscription: True
Is a guest user: False
Full access granted: True
Assignment Operators — Updating Values Without Repeating Yourself
You already know the basic assignment operator: the single equals sign (=). It stores a value into a variable. But Python gives you a set of shorthand assignment operators that combine assignment with an arithmetic operation in one step. These are called compound assignment operators, and they exist purely to save you from writing repetitive code.
Instead of writing score = score + 10, you can write score += 10. Python reads this as 'take the current value of score, add 10 to it, and store the result back in score.' Same result, less noise. Every arithmetic operator has a compound version: +=, -=, =, /=, //=, %=, and *=.
These aren't just cosmetic shortcuts. In long functions or loops, compound assignment operators make your code significantly easier to read because the variable name only appears once per line. Your eye immediately knows the variable is being updated, not reassigned from scratch. You'll see these constantly in real-world Python code, especially in loops that accumulate totals, counts, or running scores.
# ─── Assignment Operators ───────────────────────────────────────────────── # Scenario: Tracking a player's score in a simple game loop. player_score = 0 # Basic assignment: store 0 in player_score player_lives = 3 boss_health = 100 # += adds the right value to the variable and saves the result player_score += 50 # Player collected a coin: score is now 50 player_score += 100 # Player defeated an enemy: score is now 150 print("Score after two events:", player_score) # 150 # -= subtracts from the variable player_lives -= 1 # Player hit a spike: lives drop from 3 to 2 print("Lives remaining:", player_lives) # 2 # *= multiplies the variable by a value player_score *= 2 # Double score power-up activated! print("Score after double power-up:", player_score) # 300 # /= divides the variable (result is always a float) boss_health /= 2 # Boss hit by a special attack — half health print("Boss health:", boss_health) # 50.0 ← notice the .0, it becomes a float # //= floor-divides the variable (result stays a whole number) boss_health = 100 # Reset boss health for demo boss_health //= 3 # Each hit removes a third (rounded down) print("Boss health after floor division:", boss_health) # 33 # %= stores the remainder ammo_count = 17 shots_per_clip = 5 remainder_in_clip = ammo_count % 5 # How many bullets are in the partial clip? ammo_count %= 5 # ammo_count now holds only the leftover print("Bullets in partial clip:", ammo_count) # 2 # **= raises the variable to a power base_damage = 2 base_damage **= 4 # Damage scales exponentially: 2^4 print("Scaled damage:", base_damage) # 16
Lives remaining: 2
Score after double power-up: 300
Boss health: 50.0
Boss health after floor division: 33
Bullets in partial clip: 2
Scaled damage: 16
Identity, Membership and Bitwise Operators — The Powerful Trio Beginners Skip
Most beginners learn arithmetic and comparison operators and stop there. But three more categories show up constantly in real Python code, and skipping them will leave you confused when you read someone else's code.
Identity operators (is and is not) check whether two variables point to the exact same object in memory — not just whether they have equal values. This is subtle but critical. Two variables can hold the same value but be completely different objects. Use == to compare values. Use is to check if something is literally None.
Membership operators (in and not in) check whether a value exists inside a collection like a list, string, or dictionary. They read almost like plain English: if 'admin' in user_roles is as clear as code gets. You'll use these constantly when filtering data or validating input.
Bitwise operators work on the individual binary digits (bits) of integers. They look strange at first but they're essential for low-level tasks like setting feature flags, working with permissions, or processing binary data. You won't need them every day, but you absolutely need to recognise them.
# ─── Identity, Membership, and Bitwise Operators ────────────────────────── # ── IDENTITY OPERATORS: is, is not ─────────────────────────────────────── # 'is' checks if two names point to the SAME object in memory # '==' checks if two objects have the SAME VALUE response_data = None # The correct way to check for None is always 'is', not '==' if response_data is None: print("No data received from the server.") # This prints # Demonstrating the difference between 'is' and '==' list_a = [1, 2, 3] list_b = [1, 2, 3] # Same values, but a brand-new list object in memory list_c = list_a # list_c points to the SAME object as list_a print(list_a == list_b) # True — values are identical print(list_a is list_b) # False — they are different objects in memory print(list_a is list_c) # True — both names point to the same object # ── MEMBERSHIP OPERATORS: in, not in ───────────────────────────────────── # Check if a value exists inside a collection allowed_file_types = ['jpg', 'png', 'gif', 'webp'] uploaded_extension = 'pdf' if uploaded_extension not in allowed_file_types: print(f".{uploaded_extension} files are not allowed.") # This prints welcome_message = "Welcome to TheCodeForge!" if "CodeForge" in welcome_message: print("Brand name found in message.") # This prints # ── BITWISE OPERATORS ───────────────────────────────────────────────────── # These operate on binary representations of integers. # Practical use: combining permission flags (like Linux file permissions) READ_PERMISSION = 0b100 # Binary 4: the 'read' bit is ON WRITE_PERMISSION = 0b010 # Binary 2: the 'write' bit is ON EXECUTE_PERMISSION = 0b001 # Binary 1: the 'execute' bit is ON # & (AND): both bits must be 1 — used to CHECK if a permission is set # | (OR): at least one bit is 1 — used to COMBINE permissions # ~ (NOT): flips all bits # ^ (XOR): bits differ — used to TOGGLE a permission # << (left shift): multiply by powers of 2 # >> (right shift): divide by powers of 2 # Grant read and write permissions using OR user_permissions = READ_PERMISSION | WRITE_PERMISSION print("User permissions (binary):", bin(user_permissions)) # 0b110 (decimal 6) # Check if user has WRITE permission using AND has_write = user_permissions & WRITE_PERMISSION print("Has write access:", bool(has_write)) # True # Check if user has EXECUTE permission has_execute = user_permissions & EXECUTE_PERMISSION print("Has execute access:", bool(has_execute)) # False # Left shift: quick multiply by 2 base_value = 3 print("3 left-shifted by 2:", base_value << 2) # 12 (3 * 4) # Right shift: quick divide by 2 print("12 right-shifted by 2:", 12 >> 2) # 3 (12 / 4)
True
False
True
.pdf files are not allowed.
Brand name found in message.
User permissions (binary): 0b110
Has write access: True
Has execute access: False
3 left-shifted by 2: 12
12 right-shifted by 2: 3
| Operator Category | Symbols | Returns | Typical Use Case |
|---|---|---|---|
| Arithmetic | + - * / // % ** | Number (int or float) | Maths calculations, price totals, loop counters |
| Comparison | == != > < >= <= | Boolean (True/False) | Conditions in if-statements and while-loops |
| Logical | and or not | Boolean (True/False) | Combining multiple conditions into one check |
| Assignment | = += -= *= /= //= %= **= | Updated variable value | Updating running totals, scores, counters in loops |
| Identity | is is not | Boolean (True/False) | Checking if a variable is None or points to same object |
| Membership | in not in | Boolean (True/False) | Checking if a value exists in a list, string, or dict |
| Bitwise | & | ~ ^ << >> | Integer | Permission flags, binary data, low-level optimisation |
🎯 Key Takeaways
- = assigns a value, == compares values — confusing these two is the single most common Python bug for beginners and it causes a SyntaxError every time.
- The modulus operator (%) gives you the remainder after division — use it to check even/odd numbers, build cycling counters, or find leftovers when grouping items.
- Always use 'is' (not '==') to check for None — 'is' checks memory identity and cannot be tricked by a custom class overriding the equality method.
- The 'in' membership operator reads like plain English and is far more readable (and often faster) than a manual loop when checking if a value exists in a collection.
⚠ Common Mistakes to Avoid
- ✕Mistake 1: Using = instead of == in a condition — Symptom: SyntaxError: invalid syntax on your if-statement line — Fix: Always use == for comparison. Remember: = stores a value, == asks a question. If you're checking equality, you need two equals signs.
- ✕Mistake 2: Using == to compare with None — Symptom: Code works most of the time but silently fails with custom objects that override __eq__ — Fix: Always write if variable is None or if variable is not None. The is operator checks memory identity, which is the only reliable way to check for None.
- ✕Mistake 3: Expecting integer division from / (forward slash) — Symptom: 7 / 2 returns 2.5 when you expected 3 — Fix: Use // (floor division) when you need a whole-number result. The single / always returns a float in Python 3. This catches developers coming from Python 2, where / between two integers returned an integer.
Interview Questions on This Topic
- QWhat is the difference between the == operator and the is operator in Python? Can you give an example where they produce different results?
- QWhat does the modulus operator (%) actually do, and can you give two practical programming scenarios where you'd use it?
- QWhat is operator precedence in Python? If you write result = 2 + 3 * 4, what is the value of result and why — and how would you change the evaluation order?
Frequently Asked Questions
How many types of operators are there in Python?
Python has seven categories of operators: arithmetic (+, -, , /, //, %, *), comparison (==, !=, >, <, >=, <=), logical (and, or, not), assignment (=, +=, -=, etc.), identity (is, is not), membership (in, not in), and bitwise (&, |, ~, ^, <<, >>). Beginners should focus on the first four categories first — they cover 90% of everyday Python code.
What is operator precedence in Python and why does it matter?
Operator precedence determines the order Python evaluates operators when multiple appear in the same expression. Python follows PEMDAS/BODMAS rules — exponents first, then multiplication and division, then addition and subtraction. So 2 + 3 4 equals 14, not 20. Use parentheses to control the order explicitly: (2 + 3) 4 equals 20. When in doubt, add parentheses — they make intent clear to both Python and the next developer reading your code.
What is the difference between / and // in Python?
The / operator performs true division and always returns a float — even if both numbers divide evenly, so 10 / 2 gives 5.0, not 5. The // operator performs floor division and always rounds the result DOWN to the nearest whole number, returning an integer when both operands are integers. So 7 // 2 gives 3, not 3.5. Use // whenever you need a whole-number result, like calculating how many full rows fit in a grid.
Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.