Skip to main content

Operators

Operators are special symbols that perform operations on variables and values. Python provides a rich set of operators for performing calculations, comparing values, and building logical expressions.

Arithmetic Operators

Arithmetic operators perform mathematical operations on numeric values (floats (float), integers (int), and complex numbers (complex)).

OperatorNameDescriptionExampleWorks with
+AdditionAdds two values5 + 3 equals 8int, float, complex
-SubtractionSubtracts right operand from left5 - 3 equals 2int, float, complex
*MultiplicationMultiplies two values5 * 3 equals 15int, float, complex
/DivisionDivides left operand by right (result is a float)5 / 3 equals 1.6666...int, float, complex
**ExponentiationRaises left operand to power of right5 ** 3 equals 125int, float, complex
//Floor DivisionDivides and rounds down to nearest integer5 // 3 equals 1int, float
%ModulusReturns the remainder of division5 % 3 equals 2int, float
# Arithmetic operators in action
a = 15
b = 4

# This is a expression, we will continue to use this in the next lesson
x = a + b; # the value within the variable a is 15 and b is 4, so x = 19
print(f"{a} + {b} = {a + b}") # 15 + 4 = 19
print(f"{a} - {b} = {a - b}") # 15 - 4 = 11
print(f"{a} * {b} = {a * b}") # 15 * 4 = 60
print(f"{a} / {b} = {a / b}") # 15 / 4 = 3.75
print(f"{a} // {b} = {a // b}") # 15 // 4 = 3
print(f"{a} % {b} = {a % b}") # 15 % 4 = 3
print(f"{a} ** {b} = {a ** b}") # 15 ** 4 = 50625

Common Mistakes with Arithmetic Operators:

# Bad - confusing division (/) with floor division (//)
result = 5 / 2
print(result) # 2.5 (not 2)

# Bad - forgetting that regular division always returns a float
result = 10 / 5
print(result) # 2.0 (not 2)
print(type(result)) # <class 'float'>

# Bad - forgetting that % is remainder, not percentage
discount = 10 % 100 # Not a 10% discount, but the remainder of 10 ÷ 100
print(discount) # 10 (not 0.1)

# Good - calculating percentage correctly
discount_percentage = 10
price = 100
discount_amount = price * (discount_percentage / 100)
print(discount_amount) # 10.0

Assignment Operators

Assignment operators assign values to variables.

OperatorDescriptionExample
=Assigns valuex = 10
+=Add and assignx += 5 is same as x = x + 5
-=Subtract and assignx -= 3 is same as x = x - 3
*=Multiply and assignx *= 2 is same as x = x * 2
/=Divide and assignx /= 4 is same as x = x / 4
//=Floor divide and assignx //= 2 is same as x = x // 2
%=Modulus and assignx %= 3 is same as x = x % 3
**=Exponentiate and assignx **= 2 is same as x = x ** 2
# Assignment operators in action
x = 10
print(f"Initial value: x = {x}") # 10

x += 5
print(f"After x += 5: x = {x}") # 15

x -= 3
print(f"After x -= 3: x = {x}") # 12

x *= 2
print(f"After x *= 2: x = {x}") # 24

x /= 4
print(f"After x /= 4: x = {x}") # 6.0 (note it's now a float)

x //= 2
print(f"After x //= 2: x = {x}") # 3.0 (still a float)

x **= 2
print(f"After x **= 2: x = {x}") # 9.0

Common Mistakes with Assignment Operators:

# Bad - confusing = (assignment) with == (equality check)
x = 5
if x = 10: # SyntaxError: invalid syntax
print("x is 10")

# Good
if x == 10:
print("x is 10")

# Bad - forgetting that /= results in a float
count = 10
count /= 2 # also results in a float
print(count) # 5.0, not 5
print(type(count)) # <class 'float'>

# Bad - chaining assignments incorrectly
x = y += 5 # SyntaxError

# Good
y += 5
x = y

String Operators

You can also manipulate strings with certain operators.

# String operations
combined = "Hello" + " " + "World" # Concatenation
repeated = "Ha" * 3 # Repetition (HaHaHa)
length = len(name) # Length of name (5) - `len()` is a built-in function

# String indexing (accessing characters within a string
first_char = name[0] # 'A' - All sequence types (strings, lists, tuples) start indexing at 0 (NOT 1)
second_char = name[1] # 'l' - This is the second character, NOT the first
last_char = name[-1] # 'e' - this will access the last character of the string

# String slicing
substring = name[1:3] # 'li' (characters at index 1 and 2) - a slice is a range of characters
substring2 = name[:3] # 'Ali' (from start to index 2)
substring3 = name[2:] # 'lice' (from index 2 to end)
substring4 = name[-3:] # 'ice' (last 3 characters)

# String methods (these are functions that can be called on strings)
uppercase = name.upper() # 'ALICE'
lowercase = name.lower() # 'alice'
replaced = name.replace('l', 'L') # 'ALice'
split_result = "a,b,c".split(',') # ['a', 'b', 'c']
joined = '-'.join(['a', 'b', 'c']) # 'a-b-c'

Comparison Operators

Comparison operators compare values and return boolean results (True or False).

OperatorDescriptionExample
==Equal to5 == 5 returns True
!=Not equal to5 != 3 returns True
>Greater than5 > 3 returns True
<Less than5 < 3 returns False
>=Greater than or equal to5 >= 5 returns True
<=Less than or equal to5 <= 3 returns False
# Comparison operators in action
a = 10
b = 5
c = 10

print(f"{a} == {b}: {a == b}") # 10 == 5: False
print(f"{a} == {c}: {a == c}") # 10 == 10: True
print(f"{a} != {b}: {a != b}") # 10 != 5: True
print(f"{a} > {b}: {a > b}") # 10 > 5: True
print(f"{a} < {b}: {a < b}") # 10 < 5: False
print(f"{a} >= {c}: {a >= c}") # 10 >= 10: True
print(f"{a} <= {b}: {a <= b}") # 10 <= 5: False

Comparing Different Types:

Python allows comparison between different types in some cases, but this can lead to unexpected results.

# Integer and float comparison (works as expected)
print(5 == 5.0) # True

# String comparisons
print("apple" < "banana") # True
print("10" > "2") # False - compares lexicographically (as strings), this means it compares character by character. ('1' < '2')

# Mixed type comparisons (generally should be avoided)
try:
print(5 < "10") # TypeError in Python 3
except TypeError as e:
print(f"Error: {e}")

Common Mistakes with Comparison Operators:

# Bad - using = instead of == for comparison
if x = 5: # SyntaxError: invalid syntax
print("x is 5")

# Good
if x == 5:
print("x is 5")

# Bad - comparing floating point numbers directly
a = 0.1 + 0.2
b = 0.3
print(a == b) # False (due to floating-point precision)

# Good - use math.isclose for float comparisons
import math
print(math.isclose(a, b)) # True

# Bad - confusing identity (is) with equality (==)
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # False (different objects)
print(a == b) # True (same values)

Logical Operators

Logical operators combine boolean expressions and return boolean results.

OperatorDescriptionExample
andTrue if both operands are trueTrue and False returns False
orTrue if at least one operand is trueTrue or False returns True
notInverts the boolean valuenot True returns False
# Logical operators in action
x = 10
y = 5

# Using 'and' operator - both conditions must be True
print(x > 8 and y < 8) # True

# Using 'or' operator - at least one condition must be True
print(x > 12 or y < 8) # True

# Using 'not' operator - inverts the boolean value
print(x == y) # False
print(not(x == y)) # True

Common Mistakes with Logical Operators:

# Bad - confusing & (bitwise AND) with and (logical AND)
result = True & False # Works but not intended for boolean logic
print(result) # False

# Good
result = True and False
print(result) # False

# Bad - forgetting short-circuit evaluation
x = 0
result = x != 0 and 10 / x > 2 # Safe because of short-circuit
print(result) # False

# Could be dangerous if reversed:
try:
result = 10 / x > 2 and x != 0 # ZeroDivisionError
except ZeroDivisionError as e:
print(f"Error: {e}")

Identity Operators

Identity operators check if two variables refer to the same object in memory.

OperatorDescriptionExample
isTrue if both variables are the same objectx is y
is notTrue if variables are different objectsx is not y
# Identity operators
a = [1, 2, 3]
b = [1, 2, 3] # Same values but different object
c = a # Same object

print(f"a is b: {a is b}") # False - different objects in memory
print(f"a is c: {a is c}") # True - same object in memory
print(f"a == b: {a == b}") # True - same values

# Common use with None
x = None
print(f"x is None: {x is None}") # True

Common Mistakes with Identity Operators:

# Bad - using 'is' to compare values (should use ==)
a = 5
b = 5
print(a is b) # Might be True due to implementation details but shouldn't rely on it

# Especially problematic with larger integers
a = 1000
b = 1000
print(a is b) # Likely False due to how Python manages integers

# Good - use 'is' for identity, '==' for equality
a = 1000
b = 1000
print(a == b) # True - comparing values

# Good usage - checking for None, True, False
x = None
if x is None:
print("x is None")

Membership Operators

Membership operators test if a value is found in a sequence (string, list, tuple, set, or dictionary).

OperatorDescriptionExample
inTrue if value is found in sequence3 in [1, 2, 3]
not inTrue if value is not found in sequence4 not in [1, 2, 3]
# Membership operators
fruits = ["apple", "banana", "cherry"]

print(f"'banana' in fruits: {'banana' in fruits}") # True
print(f"'orange' in fruits: {'orange' in fruits}") # False
print(f"'orange' not in fruits: {'orange' not in fruits}") # True

# With strings
text = "Hello, World!"
print(f"'Hello' in text: {'Hello' in text}") # True
print(f"'Python' in text: {'Python' in text}") # False

# With dictionaries (checks keys, not values)
user = {"name": "Alice", "age": 25}
print(f"'name' in user: {'name' in user}") # True
print(f"'Alice' in user: {'Alice' in user}") # False

Common Mistakes with Membership Operators:

# Bad - forgetting that 'in' checks keys in dictionaries, not values
user = {"name": "Alice", "age": 25}
if "Alice" in user: # This won't work as expected
print("Alice is in the dictionary")

# Good - checking for values properly
if "Alice" in user.values():
print("Alice is a value in the dictionary")

# Bad - inefficient searching in large lists
large_list = list(range(10000))
# Linear search - O(n) complexity
if 9999 in large_list:
print("Found")

# Good - use sets for faster membership testing when appropriate
large_set = set(range(10000))
# Constant time - O(1) complexity
if 9999 in large_set:
print("Found")

Bitwise Operators

Bitwise operators perform operations on the binary representations of integers.

OperatorDescriptionExample
&Bitwise AND5 & 3 equals 1
|Bitwise OR5 | 3 equals 7
^Bitwise XOR5 ^ 3 equals 6
~Bitwise NOT~5 equals -6
<<Left shift5 << 1 equals 10
>>Right shift5 >> 1 equals 2
# Bitwise operators
a = 5 # 0101 in binary
b = 3 # 0011 in binary

print(f"{a} & {b} = {a & b}") # 0101 & 0011 = 0001 = 1
print(f"{a} | {b} = {a | b}") # 0101 | 0011 = 0111 = 7
print(f"{a} ^ {b} = {a ^ b}") # 0101 ^ 0011 = 0110 = 6
print(f"~{a} = {~a}") # ~0101 = 1010 (with sign) = -6
print(f"{a} << 1 = {a << 1}") # 0101 << 1 = 1010 = 10
print(f"{a} >> 1 = {a >> 1}") # 0101 >> 1 = 0010 = 2

Common Mistakes with Bitwise Operators:

# Bad - confusing bitwise operators with logical operators
result = True | False # Works but not intended for boolean logic
print(result) # 1 (not True)

# Good - use logical operators for boolean logic
result = True or False
print(result) # True

# Bad - not understanding operator precedence
result = 5 & 3 + 2 # Incorrectly assumes 5 & (3 + 2)
print(result) # Actually (5 & 3) + 2 = 1 + 2 = 3

# Good - use parentheses to clarify
result = 5 & (3 + 2) # Clear intention
print(result) # 5 & 5 = 5

Operator Precedence

Python follows a specific order when evaluating expressions with multiple operators. Here's a simplified precedence order (from highest to lowest):

  1. Parentheses ()
  2. Exponentiation **
  3. Unary operators +x, -x, ~x
  4. Multiplication, division, floor division, modulus *, /, //, %
  5. Addition and subtraction +, -
  6. Bitwise shifts <<, >>
  7. Bitwise AND &
  8. Bitwise XOR ^
  9. Bitwise OR |
  10. Comparison operators ==, !=, >, <, >=, <=
  11. Identity operators is, is not
  12. Membership operators in, not in
  13. Logical operators not, and, or
# Operator precedence examples
result1 = 10 + 5 * 2
print(f"10 + 5 * 2 = {result1}") # 20 (multiplication before addition)

result2 = (10 + 5) * 2
print(f"(10 + 5) * 2 = {result2}") # 30 (parentheses override precedence)

result3 = 10 + 5 * 2 ** 2
print(f"10 + 5 * 2 ** 2 = {result3}") # 30 (exponentiation, then multiplication, then addition)

# Complex expression
result4 = 10 + 20 * 2 > 50 and 3 ** 2 >= 2 * 4
print(f"10 + 20 * 2 > 50 and 3 ** 2 >= 2 * 4 = {result4}") # False

Best Practices for Operators:

  1. Use parentheses to make your code more readable and to ensure operations occur in the intended order
  2. Be careful with operator precedence in complex expressions
  3. Use is and is not only for comparing with None, True, False, or checking object identity
  4. Use == and != for value equality
  5. Be aware of floating-point precision issues when comparing float values
  6. Use short-circuit evaluation to your advantage in logical expressions

Operators are fundamental building blocks in Python programming. Understanding how they work and their precedence rules will help you write correct and efficient code. In the next lesson, we'll explore input and output operations in Python.