Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Python›Operators (Arithmetic, Comparison, Logical)

Foundations

Operators (Arithmetic, Comparison, Logical)

Operators are the fundamental building blocks that allow you to manipulate data, evaluate conditions, and control the flow of your program. Understanding these primitives is critical because they dictate how values interact and how complex logic is constructed from simple expressions. You reach for these operators whenever you need to calculate results, compare values, or chain multiple logical assertions into a cohesive decision-making structure.

Arithmetic Operators and Evaluation

Arithmetic operators are the primary mechanism for performing numerical computation, but they are defined by how Python interprets the relationship between numbers and the standard mathematical rules of precedence. When you use operators like addition (+), subtraction (-), multiplication (*), or true division (/), Python evaluates these from left to right, respecting order of operations where parentheses override standard priority. A subtle but crucial distinction exists between true division and floor division (//). While true division always returns a floating-point number, representing exact mathematical division, floor division discards the remainder, effectively rounding down toward negative infinity. This is essential for operations involving indices or chunking data. Furthermore, the modulo operator (%) provides the remainder of a division operation, which is the standard way to determine periodicity or cycle through fixed intervals of data without needing complex conditional branching structures.

# Demonstrating integer and float math
result = (10 + 5) * 2 / 3  # Parentheses dictate execution order
remainder = 17 % 5        # Modulo finds the remainder (2)
chunk = 17 // 5           # Floor division returns 3
print(f"Result: {result}, Remainder: {remainder}, Chunk: {chunk}")

Comparison Operators and Truthiness

Comparison operators are used to evaluate the state of data by comparing two operands and returning a boolean value (True or False) based on their identity or magnitude. These include equality (==), inequality (!=), and relational checks like less than (<) or greater than (>). Crucially, these operators trigger value comparison, which checks if the internal data represented by two objects matches, rather than checking if they are the exact same memory location. When comparing different types, Python follows strict rules; for instance, integers and floats can be compared directly, but other types might raise errors. Mastering these is necessary because they serve as the gateway for conditional logic. Whenever you write an 'if' statement, the program implicitly evaluates the expression provided using these comparison rules, deciding whether the execution path should proceed or branch elsewhere based on the result of the comparison.

# Comparing values versus checking types
x = 10
y = 10.0
is_equal = (x == y)       # Returns True because values are equivalent
is_same = (x is y)        # Returns False because types are different
print(f"Equal: {is_equal}, Same object: {is_same}")

Logical Operators for Condition Chaining

Logical operators ('and', 'or', 'not') are designed to combine multiple boolean expressions into a single consolidated truth value. Unlike arithmetic operators, these perform 'short-circuit evaluation,' which is a performance-critical behavior you must understand. When using 'and', if the first operand evaluates to false, the entire expression resolves to false immediately, and the second operand is never even computed. Similarly, for 'or', if the first operand is true, the result is true immediately. This behavior allows you to write defensive code that prevents errors; for example, you can check if a list is not empty before checking the value of its first element, effectively avoiding an 'IndexError'. By chaining these operators, you build complex business logic that expresses sophisticated requirements succinctly, ensuring your code remains readable while handling multifaceted edge cases with high efficiency and absolute safety.

# Short-circuiting prevents errors
my_list = []
# The second part is only evaluated if the first is True
if len(my_list) > 0 and my_list[0] == 1:
    print("Match found")
else:
    print("Skipped to prevent index error")

Operator Precedence and Grouping

Operator precedence determines the sequence in which different operators are evaluated in a single expression. Without a clear understanding of this, your logic might behave unpredictably, leading to subtle bugs that are difficult to trace. Arithmetic operators always take precedence over comparison operators, and comparison operators take precedence over logical operators. If you need to force a specific order of evaluation, you must use parentheses. Parentheses are not just for grouping; they are explicit documentation of your intent. They clarify exactly how the components of an expression should be partitioned. Over-relying on internal knowledge of precedence tables is considered poor practice; using explicit grouping ensures that your code is maintainable and that any developer reading your work understands the structure of the logic without needing to reference the language documentation constantly.

# Explicit grouping is better than implicit precedence
# Without parens, logical 'or' happens after comparison
status = True or False and False  # Results in True
explicit = (True or False) and False # Results in False
print(f"Implicit: {status}, Explicit: {explicit}")

Augmented Assignment Operators

Augmented assignment operators like '+=', '-=', and '*=' offer a shorthand syntax for performing an operation on a variable and assigning the result back to that same variable. While they appear to be simple syntactic sugar, they can have distinct performance implications for mutable data structures like lists or dictionaries. For primitive types like integers, the change is straightforward. However, for collections, these operators can modify the object in place rather than creating a new object in memory, which is significantly more efficient when handling large datasets. Recognizing when to use these is part of writing idiomatic code. They signal to other developers that the variable is intended to be updated iteratively during the execution process. By mastering these operators, you reduce boilerplate code and ensure your operations are performed in a manner that is both computationally optimal and syntactically clean.

# In-place modification with augmented assignment
counter = 0
counter += 10 # Shorthand for counter = counter + 10

items = [1, 2]
items += [3, 4] # Modifies original list in-place
print(f"Counter: {counter}, Items: {items}")

Key points

  • Arithmetic operators follow the standard order of operations, which can be modified using parentheses.
  • Floor division is specifically used to discard remainders and return the integer quotient of a calculation.
  • Comparison operators assess the value equivalence of objects rather than their underlying memory addresses.
  • Logical operators utilize short-circuit evaluation to prevent runtime errors by skipping unnecessary computations.
  • Operator precedence dictates that arithmetic tasks are completed before comparisons and logical checks.
  • Parentheses should be used to explicitly define logic flow to prevent ambiguity for future maintainers.
  • Augmented assignment operators are essential for modifying variables in-place, offering both clarity and performance benefits.
  • Understanding the difference between equality and identity is crucial for correctly comparing complex data structures.

Common mistakes

  • Mistake: Using '=' instead of '==' for comparison. Why it's wrong: '=' is the assignment operator; it attempts to assign a value rather than checking equality. Fix: Always use '==' when comparing two values in an if statement.
  • Mistake: Confusing integer division '//' with standard division '/'. Why it's wrong: '/' always returns a float, while '//' performs floor division. Fix: Use '//' only when you explicitly need the integer quotient, discarding the remainder.
  • Mistake: Assuming 'and'/'or' operators return a boolean. Why it's wrong: Python's logical operators return the value of one of the operands based on short-circuiting, not necessarily True or False. Fix: Use explicit boolean conversions if a True/False result is strictly required.
  • Mistake: Misunderstanding operator precedence between logical 'not' and comparison operators. Why it's wrong: Comparison operators bind more tightly than 'not', which can lead to unexpected results like 'not a == b'. Fix: Use parentheses to clarify intent, e.g., 'not (a == b)'.
  • Mistake: Expecting floating-point math to be exact. Why it's wrong: Due to binary representation of decimals, 0.1 + 0.2 != 0.3. Fix: Use the math.isclose() function to compare floats instead of direct '==' equality.

Interview questions

What are the basic arithmetic operators in Python, and how do they handle different numeric types?

Python provides standard arithmetic operators including addition (+), subtraction (-), multiplication (*), and division (/). Additionally, it features floor division (//) and the modulo operator (%). When performing operations between integers and floats, Python automatically promotes the result to a float to maintain precision. For instance, '5 / 2' results in '2.5', while '5 // 2' performs integer division returning '2'. This behavior ensures that mathematical expressions behave predictably, allowing developers to choose between exact float division and integer-based outcomes, which is essential for tasks like indexing or modular arithmetic.

How do comparison operators work in Python, and what is the significance of the 'is' versus '==' operator?

Comparison operators like '==', '!=', '>', '<', '>=', and '<=' are used to evaluate the truth value of expressions. A common point of confusion is the difference between '==' and 'is'. The '==' operator checks for equality, meaning it evaluates whether the values of two objects are the same. Conversely, the 'is' operator checks for identity, determining if both variables point to the exact same memory address. In Python, while '==' is used for general content comparison, 'is' should be reserved for comparing against singletons like 'None' or checking identity, as relying on 'is' for values can lead to unexpected bugs.

Explain how logical operators (and, or, not) function in Python and describe the concept of short-circuit evaluation.

Logical operators allow you to combine or invert boolean expressions. The 'and' operator returns the first falsy value or the last truthy value, while 'or' returns the first truthy value or the last falsy one. Python utilizes short-circuit evaluation, meaning it stops processing the expression as soon as the result is determined. For example, in 'False and some_function()', 'some_function()' is never executed. This is highly efficient and prevents errors, such as avoiding a division by zero error by checking if a divisor is non-zero before attempting the division operation.

When writing complex conditional statements, should you use nested 'if' statements or combine logical operators in a single line? Compare these two approaches.

Combining logical operators in a single line is generally preferred for readability and conciseness, especially when checking multiple conditions simultaneously. For example, using 'if x > 0 and x < 10:' is much cleaner than nesting two 'if' statements. However, nested 'if' structures are superior when the logic branches significantly or when you need to perform an expensive check only after a preliminary condition is met. While single-line logical combinations are faster to read for simple filters, deep nesting should be avoided to prevent code smell, opting instead for guard clauses or helper functions to maintain clean, logical flows.

How does operator precedence affect the execution of a Python expression, and how can you manage it?

Operator precedence determines the order in which Python evaluates parts of an expression. For instance, multiplication and division always occur before addition and subtraction. If you have an expression like '3 + 4 * 2', it will result in '11' rather than '14' because the multiplication is performed first. To manage this and ensure the code performs exactly as intended, developers should always use parentheses to explicitly group operations. Using parentheses not only overrides the default precedence but also makes the code significantly more readable for other developers, reducing the likelihood of logic errors caused by subtle order-of-operation mistakes.

Explain how logical operators behave when applied to non-boolean types, and why this is a powerful feature in Python.

In Python, logical operators do not strictly return 'True' or 'False'. Instead, they return the actual objects involved based on their truthiness. An empty list, an empty string, or the integer '0' are considered falsy, while non-empty structures are truthy. This is incredibly powerful because it allows for concise patterns like 'result = list_data or [0]'. Here, if 'list_data' is empty, 'result' defaults to '[0]'. This behavior eliminates the need for verbose 'if-else' blocks, enabling developers to write more expressive and idiomatic Python code that naturally handles default values and null-like checks during assignment.

All Python interview questions →

Check yourself

1. What is the result of the expression: 10 // 3 + 1?

  • A.4.33
  • B.3
  • C.4
  • D.4.0
Show answer

C. 4
Floor division // takes precedence over addition. 10 // 3 is 3, and 3 + 1 is 4. Option 0 is the result of true division, option 1 is the floor result without the addition, and option 3 is a float, which the // operator does not return when applied to integers.

2. What is the output of: 5 > 3 and 2 < 4?

  • A.True
  • B.False
  • C.2
  • D.5
Show answer

A. True
Both comparisons evaluate to True. 'True and True' results in True. Option 1 is incorrect because the condition is met. Options 2 and 3 are incorrect because logical operators return the boolean result of the expression when both operands evaluate to boolean True/False.

3. What is the value of: 10 or 20?

  • A.True
  • B.False
  • C.10
  • D.20
Show answer

C. 10
The 'or' operator returns the first truthy value. Since 10 is non-zero (truthy), it is returned immediately. Options 0 and 1 are incorrect because the operator returns the operand, not a boolean, and option 3 is ignored due to short-circuiting.

4. What is the result of the expression: 5 == 5.0?

  • A.True
  • B.False
  • C.None
  • D.Error
Show answer

A. True
Python compares the numeric value of 5 and 5.0, finding them equal. Option 1 is wrong because numeric equality ignores type differences. Options 2 and 3 are wrong because this is a valid arithmetic comparison.

5. Which of the following is equivalent to: not (x == y or x > z)?

  • A.not x == y or x > z
  • B.x != y and x <= z
  • C.x != y or x <= z
  • D.not x == y and not x > z
Show answer

B. x != y and x <= z
Applying De Morgan's Law, 'not (A or B)' is 'not A and not B'. Thus, 'not (x == y)' is 'x != y' and 'not (x > z)' is 'x <= z'. Option 0 lacks grouping, option 2 uses the wrong logical operator, and option 3 is equivalent but less idiomatic than using direct inequality operators.

Take the full Python quiz →

← PreviousVariables and Data TypesNext →Strings and String Methods

Python

78 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app