Operators Overview

Programming is essentially "performing operations on data." In Lesson 02 we learned about variables; now let's learn about operators — what computational capabilities Python offers. Arithmetic, comparison, logical decisions, string concatenation... After this lesson, you'll solve many real-world problems with Python.


1. Arithmetic Operators

We've used a few operators in Lesson 02. Here's the complete list:

Operator Name Example Result Notes
+ Addition 5 + 3 8 Also works for string concatenation
- Subtraction 5 - 3 2 Also used as negation: -5
* Multiplication 5 * 3 15 Also works for string repetition
/ Division 5 / 3 1.666... Always returns a float
// Floor division 5 // 3 1 Rounds down, discards fractional part
% Modulo 5 % 3 2 Remainder of division
** Exponentiation 5 ** 3 125 5 to the power of 3

Two Operators Worth Noting

/ (Division) quirk:

PYTHON
print(4 / 2)    # Output 2.0, not 2

Many people pause at this: 4 divided by 2 is clearly 2, so why does Python output 2.0? Because Python's / always returns a float, even when divisible evenly. This keeps results predictable — you see / and know the result will be float.

// (Floor division) trap:

PYTHON
print(7 // 3)     # Output 2 (7 ÷ 3 = 2.333, floored = 2)
print(-7 // 3)    # Output -3 ← may not be what you expect

-7 // 3 gives -3, not -2. Python's // is floor division (rounds toward negative infinity), not "truncation toward zero." On the number line, -2.333 floored is -3. If you want truncation toward zero, use int(-7 / 3), which gives -2.

💡 Tip: Think of // as "floor division" rather than "integer division" — "integer division" implies truncation, which doesn't hold for negative numbers.

Example: Inches and Centimeters Conversion (Difficulty ⭐)

PYTHON
# Inches to centimeters: 1 inch = 2.54 cm

# A standard ruler length
inches = 12

# Convert using multiplication
cm = inches * 2.54

# Output (notice cm is automatically a float)
print(f"{inches} inches = {cm} cm")

# Reverse: cm → inches (using division)
cm_value = 30
inches_value = cm_value / 2.54
print(f"{cm_value} cm = {inches_value:.2f} inches")

# Try floor division and modulo — how many 5-inch segments in 12 inches?
count = 12 // 5   # Floor: 2
remainder = 12 % 5  # Modulo: 2 inches remaining
print(f"12 inches can be divided into {count} segments of 5 inches, with {remainder} inches left")
▶ Try it Yourself

Output:

TEXT
12 inches = 30.48 cm
30 cm = 11.81 inches
12 inches can be divided into 2 segments of 5 inches, with 2 inches left

2. Comparison Operators

Comparison operators evaluate relationships between values and always return a boolean (True or False). They're the foundation of conditional logic.

Operator Name Example Result
== Equal to 5 == 3 False
!= Not equal to 5 != 3 True
> Greater than 5 > 3 True
< Less than 5 < 3 False
>= Greater than or equal 5 >= 5 True
<= Less than or equal 5 <= 3 False
PYTHON
age = 18
print(age == 18)     # True (exactly 18)
print(age != 18)     # False (not "not equal")
print(age > 21)      # False (not old enough for US drinking age)
print(age >= 18)     # True (exactly adult age, meets the condition)

Chained Comparisons

Python supports a concise syntax rare in other languages:

PYTHON
x = 15
print(10 < x < 20)   # True (equivalent to 10 < x and x < 20)
print(0 < x < 10)    # False

This reads more naturally than 10 < x and x < 20, like mathematical notation.

is and is not (Identity Comparison)

Strictly speaking, is isn't a comparison operator, but it's often compared with ==:

PYTHON
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)     # True (same contents)
print(a is b)     # False (but not the same object)
print(a is c)     # True (c is just an alias for a)

In daily development, 99% of the time you use ==. The convention is to use is only when checking for None: if result is None:.

Example: Race Group Classification (Difficulty ⭐)

PYTHON
# 100-meter sprint grouping rules
# Age 12–15 → Junior group
# Age 16–20 → Youth group

participant_age = 14

# Use comparison operators to determine the group
is_teen_group = 12 <= participant_age <= 15    # Chained comparison
is_youth_group = participant_age >= 16 and participant_age <= 20

print(f"Participant age: {participant_age}")
print(f"Junior group (12-15): {is_teen_group}")
print(f"Youth group (16-20): {is_youth_group}")

# Using == and !=
age_verified = True
print(f"Age verified: {age_verified == True}")
print(f"Age not verified: {age_verified != True}")
▶ Try it Yourself

Output:

TEXT
Participant age: 14
Junior group (12-15): True
Youth group (16-20): False
Age verified: True
Age not verified: False

3. Logical Operators

Logical operators combine multiple conditions, and the result is also a boolean. They're used everywhere in if statements and loop conditions.

Operator Name Example Result Notes
and Logical AND True and False False True only if both are true
or Logical OR True or False True True if at least one is true
not Logical NOT not True False Negation
PYTHON
age = 20
has_id_card = True

# and: both conditions must be met
print(age >= 18 and has_id_card)   # True (adult and has ID)

# or: at least one condition
print(age >= 18 or has_id_card)    # True (actually both are met)

# not: negation
print(not has_id_card)             # False (not True = False)

Truth Table

a b a and b a or b not a
True True True True False
True False False True False
False True False True True
False False False False True

Short-Circuit Evaluation

Python's logical operators have an important feature: short-circuit evaluation.

PYTHON
# For and: if the left side is False, the right side is never evaluated
def say_yes():
    print("say_yes was called")
    return True

print(False and say_yes())   # Output False — say_yes never ran
print(True and say_yes())    # Output "say_yes was called" and True

# For or: if the left side is True, the right side is not evaluated
print(True or say_yes())     # Output True — say_yes never ran

This is very useful in practice:

PYTHON
# Only get username if user exists — avoids None.get() error
user = None
username = user and user.get("name")   # user is None (falsy), short-circuits, username = None
print(username)                        # None

user = {"name": "Xiao Ming"}
username = user and user.get("name")   # user is truthy, evaluates right side, username = "Xiao Ming"
print(username)                        # Xiao Ming
💡 Tip: Short-circuit evaluation not only improves performance but also prevents errors. The user and user.get("name") pattern is common in Python — it ensures "safe access": if the left side is falsy, return it directly without evaluating the potentially error-prone right side.

Example: Check if a Number is "Special" (Difficulty ⭐⭐)

Combine comparison and logical operators to check if a number meets certain "special conditions."

PYTHON
# Check if a number is "special"
# Definition: between 10-99, and is a multiple of 7 or contains the digit 7

num = 49

# Condition 1: between 10-99 (chained comparison)
in_range = 10 <= num <= 99

# Condition 2: multiple of 7 (modulo + comparison)
multiple_of_7 = num % 7 == 0

# Condition 3: contains digit 7 (tens digit = 7 or ones digit = 7)
tens_digit = num // 10    # Extract tens digit
ones_digit = num % 10     # Extract ones digit
contains_7 = (tens_digit == 7) or (ones_digit == 7)

# Combine all conditions with logical operators
is_special = in_range and (multiple_of_7 or contains_7)

print(f"Number: {num}")
print(f"In range (10-99): {in_range}")
print(f"Multiple of 7: {multiple_of_7}")
print(f"Contains digit 7: {contains_7}")
print(f"Is special: {is_special}")     # True — 49 is a multiple of 7

# Verify short-circuit — if first condition fails, the rest won't run
num2 = 200  # Out of range
is_special2 = (10 <= num2 <= 99) and (num2 % 7 == 0)
print(f"\nNumber {num2}: first condition is False, second won't execute — {is_special2}")
▶ Try it Yourself

Output:

TEXT
Number: 49
In range (10-99): True
Multiple of 7: True
Contains digit 7: False
Is special: True

Number 200: first condition is False, second won't execute — False

4. Assignment Operators

Beyond basic =, Python provides compound assignment operators:

PYTHON
x = 10         # Basic assignment
x += 3         # Equivalent to x = x + 3, result: 13
x -= 2         # Equivalent to x = x - 2, result: 11
x *= 2         # Equivalent to x = x * 2, result: 22
x /= 4         # Equivalent to x = x / 4, result: 5.5
x //= 2        # Equivalent to x = x // 2, result: 2.0
x %= 2         # Equivalent to x = x % 2, result: 0.0
x = 3        # Equivalent to x = x  3, result: 0.0

Note that x = 10 is an integer, but after x /= 4 it becomes 5.5 (float), because / always returns a float. Use //= if you need an integer result.

PYTHON
# Typical increment in a loop
score = 0
score += 10      # Add 10 points
score += 20      # Add another 20
score += 15      # Add another 15
print(f"Final score: {score}")   # 45

# Strings also work with compound assignment
message = "Hello"
message += " "   # Add a space
message += "World"
print(message)               # "Hello World"
💡 Tip: x += 1 is Python's way of "increment by 1." Other languages write x++. Python has no ++ operator; use += 1.


5. String Operators

Strings have their own "operations" — not exactly mathematical, but using the same symbols.

Operator Purpose Example Result
+ Concatenation "Hello" + " " + "World" "Hello World"
* Repetition "Ha" * 3 "HaHaHa"
in Membership "Py" in "Python" True
not in Non-membership "xyz" not in "Python" True
PYTHON
# String concatenation
first_name = "Zhang"
last_name = "San"
full_name = first_name + last_name
print(full_name)              # Output "Zhang San"

# String repetition — great for drawing separator lines
line = "=" * 30
print(line)                   # Output 30 equals signs

# Membership check (in / not in)
text = "Hello, Python!"
print("Python" in text)       # True — "Python" is part of text
print("Java" in text)         # False — text doesn't contain "Java"
print("Java" not in text)     # True — indeed "not in there"
⚠️ Note: + only works between two strings, not between a string and a number. "Age: " + 25 will error. Convert the number first: "Age: " + str(25). * only works between a string and an integer — "AB" * 3 is fine, "AB" * "CD" is not.

Example: Generate a Business Card with String Operations (Difficulty ⭐⭐)

PYTHON
# Generate a simple business card using string operations

name = "Li Ming"
title = "Python Engineer"
company = "Tech Co., Ltd."

# Concatenate card content with +
card_line1 = "Name: " + name
card_line2 = "Title: " + title
card_line3 = "Company: " + company

# Generate separator with *
separator = "-" * 25

# Combine into full card
business_card = separator + "\n" + card_line1 + "\n" + card_line2 + "\n" + card_line3 + "\n" + separator

print("Generated Business Card:")
print(business_card)

# Check if it contains specific info with in
search_term = "Python"
print(f"\nDoes card contain \"{search_term}\"? {search_term in business_card}")

# Exclude certain info with not in
print(f"Card doesn't contain \"Manager\": {\"Manager\" not in business_card}")
▶ Try it Yourself

Output:

TEXT
Generated Business Card:
-------------------------
Name: Li Ming
Title: Python Engineer
Company: Tech Co., Ltd.
-------------------------

Does card contain "Python"? True
Card doesn't contain "Manager": True

6. Operator Precedence

Just like math has "multiplication before addition," Python has operator precedence.

Priority Category Operators Notes
High Exponentiation ** Right-associative
Unary +x, -x, not Positive/negative, logical NOT
Arithmetic *, /, //, % Multiply, divide, floor, modulo
Arithmetic +, - Add, subtract
Comparison ==, !=, >, <, >=, <= Comparisons
Logical not Logical NOT
Logical and Logical AND
Logical or Logical OR
Low Assignment =, +=, etc. Assignment
PYTHON
# Multiplication before addition
result = 2 + 3 * 4
print(result)                # 14 (3*4=12, then +2)

# Comparison has lower priority than arithmetic
print(2 + 3 * 4 > 10)        # True (14 > 10)

# Logical has lowest priority — do comparisons first, then combine logically
age = 20
print(age > 18 and age < 60)  # True (first age>18 and age<60, then and)

# Exponentiation is right-associative
print(2  3  2)            # 512 (first 3²=9, then 2⁹=512)
print((2  3)  2)          # 64 (with parentheses, first 2³=8, then 8²=64)

# Parentheses change precedence — just like math
result = (2 + 3) * 4
print(result)                 # 20 (first 2+3=5, then ×4)

Example: Mortgage Calculator (Difficulty ⭐⭐)

PYTHON
# Calculate monthly mortgage payment (equal payment)
# Formula: monthly = loan × monthly_rate × (1 + monthly_rate)^months ÷ [(1 + monthly_rate)^months - 1]

# Assume 1,000,000 loan, 4.5% annual rate, 30 years
loan_amount = 1_000_000    # Total loan (underscores are for readability, Python 3.6+)
annual_rate = 0.045        # Annual interest rate
years = 30
months = years * 12        # Number of payments
monthly_rate = annual_rate / 12   # Monthly interest rate

# Break it down step by step
rate_power = (1 + monthly_rate) ** months         # (1 + monthly rate)^months
numerator = loan_amount * monthly_rate * rate_power   # Numerator
denominator = rate_power - 1                          # Denominator

monthly_payment = numerator / denominator

print(f"Loan amount: {loan_amount:,} yuan")
print(f"Annual rate: {annual_rate * 100}%")
print(f"Loan term: {years} years")
print(f"Monthly payment: {monthly_payment:.2f} yuan")
print(f"Total repayment: {monthly_payment * months:,.2f} yuan")
print(f"Total interest: {monthly_payment * months - loan_amount:,.2f} yuan")
▶ Try it Yourself

Output:

TEXT
Loan amount: 1,000,000 yuan
Annual rate: 4.5%
Loan term: 30 years
Monthly payment: 5,066.85 yuan
Total repayment: 1,824,066.95 yuan
Total interest: 824,066.95 yuan
💡 Tip: The underscores in 1_000_000 are just for human readability — Python ignores them. This is a Python 3.6+ feature for visual number separation. Can't remember precedence? Use parentheses — the formula above is clear to anyone with parentheses.


7. Floating-Point Precision Issues

Every programmer encounters this:

PYTHON
print(0.1 + 0.2)                     # Output 0.30000000000000004
print(0.3)                           # Output 0.3
print(0.1 + 0.2 == 0.3)              # Output False ← they're not equal!

This isn't a Python bug — it's a fundamental limitation of storing floats in binary. Just as decimal can't precisely represent 1/3 = 0.33333..., binary can't precisely represent 0.1.

When to Watch Out

PYTHON
# Correct way to compare floats
result = 0.1 + 0.2
epsilon = 1e-10     # A very small number, about 0.0000000001
print(abs(result - 0.3) < epsilon)   # Output True
PYTHON
print(f"{0.1 + 0.2:.2f}")   # Output 0.30
PYTHON
# Real example: adding 0.1 ten times
total = 0.0
for i in range(10):
    total += 0.1
print(f"Accumulated result: {total}")          # 0.9999999999999999
print(f"Exactly 1.0: {total == 1.0}")          # False
print(f"Formatted: {total:.2f}")               # 1.00 — display is fine
⚠️ Note: For everyday learning, floating-point precision won't affect your understanding of programming logic. Just remember two rules: "don't use == to compare floats directly" and "use the decimal module for money."


8. Numeric Type Conversion

Python provides several functions for converting between numeric types:

PYTHON
# int → float
print(float(3))             # Output 3.0

# float → int (truncates toward zero, not rounding)
print(int(3.14))            # Output 3
print(int(-2.8))            # Output -2 (truncation toward zero)

# string → number (only if the string actually represents a number)
print(int("42"))            # Output 42
print(float("3.14"))        # Output 3.14

# number → string
print(str(3.14))            # Output "3.14"

# int() can also specify base
print(int("FF", 16))        # Output 255 (hexadecimal FF to decimal)
print(int("1010", 2))       # Output 10 (binary 1010 to decimal)

Example: Type Conversion in Practice (Difficulty ⭐)

PYTHON
# Full workflow: input → convert → calculate → output
user_input = "25"       # Note: this is a string, not a number

# What happens without conversion?
# print(user_input + 5)  ← uncomment to see the error

# Correct approach: convert with int() first
age = int(user_input)

# Now arithmetic works normally
age_next_year = age + 1
print(f"You entered: {user_input} (type: {type(user_input)})")
print(f"After conversion: {age} (type: {type(age)})")
print(f"Next year you'll be {age_next_year} years old")

# Reverse: convert result back to string for output
output_message = "You are " + str(age) + " years old"
print(output_message)
▶ Try it Yourself

Output:

TEXT
You entered: 25 (type: <class 'str'>)
After conversion: 25 (type: <class 'int'>)
Next year you'll be 26 years old
You are 25 years old

Common Use Cases


❓ FAQ

Q What's the difference between == and is? When should I use each?
A == compares values ("are the contents the same?"), is compares identity ("are they the same object?"). Example: a = [1, 2]; b = [1, 2]; c = aa == b is True (same values), but a is b is False (different list objects); a is c is True (c is just an alias). In daily development, 99% of the time use ==. For checking None, convention is is: if result is None:. ⚠️ Q: What pitfalls does short-circuit evaluation of and/or have in practice? A: The most common pitfall: user_input = input() or "default" — if input() returns an empty string (falsy), or short-circuits and takes the default. This is common but can be confusing for beginners. Another trap: putting a function call on the right side of and — if the left side is falsy, the function won't execute, potentially skipping important operations. Good practice: if the right expression has side effects, don't rely on short-circuit behavior; write separate statements. Q: When should I use / vs //? A: If you need a precise decimal result (e.g., 7 ÷ 3 = 2.333...), use /. If you only need an integer result (e.g., dividing 7 apples among 3 people — 2 each, 1 left over), use // with %. If you're a beginner and unsure, use / by default — at least you won't lose precision. Switch to // when you specifically need integer results. Q: What does right-associative mean? Why is it designed this way? A: Right-associative means 2 3 2 is parsed as 2 (3 2), i.e., first calculate 3² = 9, then 2⁹ = 512. Left-to-right would give (2³)² = 8² = 64, a completely different result. This matches mathematical convention: a^b^c is interpreted starting from the upper right. Use parentheses to force order: (2 3) ** 2 gives 64.

📖 Summary

  • 7 arithmetic operators: + - * / // % **; / always returns float, // floors toward negative infinity
  • 6 comparison operators: == != > < >= <=; Python supports chained comparison like 10 < x < 20
  • 3 logical operators: and (true if both true), or (true if at least one is true), not (negation); all use short-circuit evaluation
  • String operators: + concatenation, * repetition, in/not in membership
  • Precedence: ** > unary > arithmetic > comparison > not > and > or > assignment. When in doubt, use parentheses
  • Floats can't be precisely compared with ==; use difference checking abs(a - b) < epsilon

📝 Exercises

  1. Basic (Difficulty ⭐): Define a=10, b=3, c=20. Calculate and output: a + b * c, (a + b) * c, a ** b, a // b, c % a, a > b and c > 15. Guess the results first, then verify.

  2. Intermediate (Difficulty ⭐⭐): Given year = 2026, determine if it's a leap year. Leap year rule: divisible by 4 but not by 100, or divisible by 400. Hint: year % 4 == 0 checks divisibility by 4.

  3. Challenge (Difficulty ⭐⭐⭐): Write a simple temperature alarm system. Given current_temp = 38, high_alarm = 37, low_alarm = 5. Trigger an alarm if the current temperature exceeds the high limit or drops below the low limit. If the temperature is near the edge (within ±2 degrees), issue a "caution" instead of "alarm." Use only arithmetic, comparison, and logical operators. Hint: abs(current_temp - high_alarm) <= 2 checks if near the high edge.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏