Logical and relational operators let your Python code make decisions based on comparisons. They are the building blocks for conditions in if statements and loops, which you will see on the PCEP-30-02 exam. Without them, your programs could never react differently to different situations.
Jump to a section
A simple way to picture Logical and Relational Operators
Before you are allowed to board a flight, a series of conditions must all be met. First, you present your boarding pass and ID at the document check, which leads to a decision: are both your ID and boarding pass valid? This is a logical 'and' condition — both the ID check must pass and the boarding pass check must pass for you to proceed. If either fails, you are stopped.
Next, you walk through the metal detector. The alarm is triggered if you have metal on you or if you have prohibited items in your bag. This is a logical 'or' condition: if the metal detector beeps or the X-ray machine flags your bag, you get pulled aside for a secondary search.
The final gate agent checks your passport number against a list. Is your passport number equal to the number on the manifest? If it is not, you cannot board. This is a relational operator — comparing two values (your passport number and the manifest number) to see if they are equal. The whole process uses relational operators (is your ID expiry date later than today?) and logical operators (combining multiple checks) to decide one thing: whether you get on the plane. Just like in Python, the airport's decision tree is built from simple yes/no conditions combined with 'and', 'or', and 'not'.
Logical and relational operators are tools that let your Python code ask true/false questions about data. A relational operator compares two values and gives you back either True or False. The most common ones are: == (equal to), != (not equal to), < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to). For example, the expression 5 < 3 asks 'is 5 less than 3?' and produces the answer False. The expression 'hello' == 'hello' asks 'is the string hello equal to the string hello?' and produces True.
Logical operators combine multiple true/false values. In Python, the three logical operators are 'and', 'or', and 'not'. The 'and' operator gives you True only if both conditions on its left and right are True. The 'or' operator gives you True if at least one of the conditions is True. The 'not' operator flips a True to False and a False to True. For example, (5 > 3) and (10 < 20) asks 'is 5 greater than 3 and is 10 less than 20?' Both are True, so the whole expression is True. If you wrote (5 > 3) or (10 > 20), that gives True because the first part is True even though the second is False. The expression not (5 > 3) becomes False because (5 > 3) is True.
These operators replace the need to list every possible outcome manually. Instead of writing out 'if the user is an admin, then show the settings; if the user is not an admin, then hide the settings', you use a relational comparison (user_role == 'admin') and let Python evaluate it.
Why do they exist? Because real programs must react to different inputs. A calculator app uses relational operators to check which button was pressed. A login system uses relational operators (compare the entered password to the stored password) and logical operators (check that the username is correct and the account is not locked).
For PCEP-30-02, you must memorise the exact symbols and their precedence. Precedence means the order in which Python evaluates operators when they appear together. The highest precedence goes to 'not', then relational operators, then 'and', then 'or'. So in the expression not 5 > 3 or 8 == 8 and 2 < 1, Python first evaluates not (5 > 3) which becomes False, then (8 == 8) which is True, then (2 < 1) which is False, then True and False gives False, then False or False gives False.
You also need to know that Python treats truthy and falsy values. Any non-zero number, non-empty string, or non-empty list is treated as True in a logical context. The number 0, the empty string '', the empty list [], and None are treated as False. This matters for short-circuit evaluation: in an 'and' chain, if the first condition is False, Python stops evaluating because the whole thing cannot be True. In an 'or' chain, if the first condition is True, Python stops because the whole thing is already True.
The typical exam question shows a mixed expression with relational and logical operators and asks you to predict the result (True or False). They love to test the difference between = (assignment) and == (equality). Another favourite is asking what happens when you compare incompatible types, like '5' == 5 (string versus integer) which is False. They also test operator chaining: 3 < 5 < 7 is a valid Python expression meaning (3 < 5) and (5 < 7), and it evaluates to True.
Identify the values you need to compare
Look at your problem and pick out two pieces of data that you want to compare. For example, if you are checking if a user is old enough, the two values are the user's age and the minimum age (like 18). Write them down as variables or literals.
Choose the correct relational operator
Decide which relationship you need: equality (==), inequality (!=), less than (<), greater than (>), less than or equal (<=), or greater than or equal (>=). For the age example, you would use >= because you want to check if the user is 18 or older.
Write the relational expression
Combine the two values with the operator: user_age >= 18. This expression will be evaluated by Python as either True or False. Remember that strings compared with numbers always give False, so make sure both values are the same type.
Combine multiple conditions with logical operators
If you have more than one condition, use and, or, or not to join them. For example, to check that a user is both over 18 and has an active subscription, write: user_age >= 18 and subscription_status == 'active'. Use parentheses to control the order of evaluation: (condition1 or condition2) and condition3.
Evaluate the final boolean value
Python follows precedence rules (not first, then relational operators, then and, then or) and short-circuit rules to compute the final True or False. If you are unsure, add parentheses to make the order explicit. The result is used by an if statement to decide which block of code to run.
Test edge cases
Check what happens with boundary values (like exactly 18 for the age check), with falsy values (0, empty string, None), and with unexpected types. For example, test user_age = 0 to ensure the condition works correctly (it should be False).
An IT professional, say a junior developer, uses logical and relational operators daily. Consider a typical ticket system for a small company. The developer is asked to write a script that automatically assigns priority to incoming support tickets. The tickets have fields: customer_plan (free or premium), hours_since_first_contact (integer), and has_attached_logs (True or False). The business rule says: 'A ticket gets high priority if the customer is on a premium plan and the ticket is older than 48 hours, or if the ticket has attached logs that indicate a system crash.' The developer writes a condition like:
if (customer_plan == 'premium' and hours_since_first_contact > 48) or (has_attached_logs and log_content_mentions_crash): priority = 'high'
This uses relational operators (==, >) and logical operators (and, or). The developer must be careful with parentheses: without them, Python might group the conditions differently because 'and' binds tighter than 'or'. That would change the logic.
Another example: the developer writes a function that validates user input. The user must enter an age between 18 and 65 inclusive. The condition is:
if age >= 18 and age <= 65: print('Valid age')
They could also use Python's chaining: if 18 <= age <= 65. Both work. But the developer must check edge cases — what if the user enters a string? The relational operator >= would raise a TypeError because you cannot compare a string to an integer. So the developer first checks the type using type(age) == int.
In testing environments, developers write unit tests that use relational operators to check expected outcomes. If a function is supposed to return the sum of two numbers, the test uses an if statement with == to compare the actual result to the expected result. - When debugging, developers add temporary print statements that show the value of boolean expressions. For example: print(is_logged_in and has_permission == 'admin') - When configuring access control, they use logical operators to combine role checks: if role == 'admin' or role == 'manager': allow access - When processing data pipelines, they use relational operators to filter rows: if value > threshold: flag row
The key skill for an IT professional is to translate business rules into correct boolean logic. A common real-world mistake is missing the difference between 'and' and 'or' — for example, a condition that should be 'customer is premium or customer has priority support add-on' being written with 'and' instead, which locks out customers who have only one of the two.
The PCEP-30-02 exam tests objective 3.1: 'Use comparison and logical operators to build conditions.' This objective appears in multiple-choice and short-answer questions. The exam loves to check whether you know the exact symbols, operator precedence, short-circuit evaluation, and truthy/falsy behaviour. - Question type 1: 'What is the value of the following expression?' They give you something like 5 == 5.0 or 3 < 2 and 4 > 1. You must compute the result. The trap: some beginners forget that 5 and 5.0 are equal in value even though they are different types (int and float). The answer is True. - Question type 2: 'Which of the following expressions evaluates to True?' with four options mixing logical and relational operators. They include one option with wrong parentheses to test if you know that and binds tighter than or. - Question type 3: 'What does the following code print?' They give a short script with an if-elif-else and ask you to trace the logic. - Question type 4: 'What is the result of the expression: not True and False?' The answer is False. Many beginners mistakenly think 'not' applies to the whole expression, but it binds only to True, so not True becomes False, then False and False is False. - Question type 5: 'Which operator is used to check if two values are not equal?' The answer is !=. They might also ask about the difference between = and ==.
Traps they set:
Chaining syntax: 3 < 5 < 7 is valid, but they might write 3 < 5 and 5 < 7 separately and ask you to recognise it is equivalent.
Short-circuit evaluation: In the expression False and some_function(), some_function() never executes. They might ask 'what is the output of this code' where a print statement inside the function would not be executed.
Truthy values: They test that 0, '', [], None are False, and any non-zero number, non-empty string, or non-empty list is True. A classic trap: if []: print('yes') — nothing is printed because [] is falsy.
Operator precedence: A multi-operator expression without parentheses. You must memorise that not > relational > and > or.
Concepts to memorise:
The six relational operators: ==, !=, <, >, <=, >=
The three logical operators: and, or, not
Python's truthiness rules for non-boolean values
Short-circuit behaviour
The fact that comparing different numeric types (int vs float) works, but comparing strings to numbers gives True for == only if the string cannot be converted (e.g., '5' == 5 is False)
How chaining works: x < y < z is equivalent to x < y and y < z
Relational operators (==, !=, <, >, <=, >=) compare two values and return a boolean True or False.
Logical operators (and, or, not) combine or invert boolean values to form complex conditions.
In Python, operator precedence from highest to lowest is: not, then relational operators, then and, then or.
The expression 3 < 5 < 7 uses chaining and is equivalent to (3 < 5) and (5 < 7).
Short-circuit evaluation means that in an 'and' chain, evaluation stops at the first False; in an 'or' chain, it stops at the first True.
The 'not' operator always returns a boolean value, even if its operand is a non-boolean like an integer or string.
These come up on the exam all the time. Here's how to tell them apart.
= (Assignment)
Used to assign a value to a variable, e.g., x = 5
Does not return a value that can be used in an if condition
Using = inside a condition causes SyntaxError
== (Equality)
Used to compare two values for equality, e.g., x == 5
Returns a boolean True or False
Allowed inside if conditions, e.g., if x == 5:
and (Logical)
Returns True only if both operands are truthy
Short-circuits on the first falsy operand
Binds tighter than or in precedence
or (Logical)
Returns True if at least one operand is truthy
Short-circuits on the first truthy operand
Binds looser than and in precedence
is (Identity)
Checks if two variables refer to the same object in memory
Returns True only for identical objects
Usually used with None: variable is None
== (Equality)
Checks if two values are equal in value
Returns True for equivalent values even if different objects
Used for comparing numbers, strings, and other data
Truthy Values
Any non-zero number (e.g., 1, -5, 3.14)
Any non-empty sequence (e.g., 'hello', [1, 2])
The boolean True itself
Falsy Values
The number 0 and 0.0
Empty sequences: '', [], (), {}
The boolean False and the None value
Operator Chaining (3 < 5 < 7)
Python syntax: a < b < c
Each operand is evaluated only once
Equivalent to (a < b) and (b < c)
Explicit and (3 < 5 and 5 < 7)
Requires writing two comparisons
The middle operand (b) is evaluated twice
Gives the same result but is more verbose
Mistake
The = operator is used to check if two values are equal.
Correct
In Python, = is the assignment operator used to assign a value to a variable. The equality operator is == (two equals signs). Using = inside a condition causes a syntax error because Python does not allow assignment inside expressions like if.
In mathematics, a single equal sign means equality, so beginners naturally transfer that habit to programming. Other languages like JavaScript allow = inside conditions (though it is usually a bug), but Python explicitly disallows it, which confuses newcomers.
Mistake
The expression 3 < 5 < 7 is invalid and will cause an error.
Correct
Python supports operator chaining. 3 < 5 < 7 is perfectly valid and is evaluated as (3 < 5) and (5 < 7), which is True.
Most other programming languages do not support chaining, so beginners coming from C++, Java, or JavaScript assume Python also forbids it. The Python behaviour is unique and is often not taught in introductory tutorials.
Mistake
The 'and' operator returns a boolean value only (True or False).
Correct
In Python, 'and' returns the first falsy value if any operand is falsy, or the last operand if all are truthy. For example, 0 and 5 returns 0 (not False). Similarly, 'or' returns the first truthy value or the last operand if all are falsy. This is because Python evaluates operands lazily and returns the actual value, not just True or False.
Many beginners learn that logical operators return booleans because that is true in most other languages. Python's behaviour is an optimisation that also allows concise idioms like x = user_input or 'default'. Beginners who expect only True/False are confused when they see a non-boolean value returned.
Mistake
The 'not' operator always changes True to False and False to True, so not 5 gives False.
Correct
The 'not' operator first converts its operand to a boolean using truthiness rules. 5 is truthy, so not 5 returns False (the boolean). However, 'not' does not return a value of the original type; it always returns a boolean. So not 'hello' returns False, not the string 'hello'.
Because 'not' is a unary operator that sounds like it should negate the value, beginners think it flips truthiness but keeps the type. They might expect not 'hello' to return '' (empty string) because that is the opposite truthy value. But Python consistently returns a boolean from 'not'.
Mistake
Comparing a string to a number like '5' == 5 returns True because they look similar.
Correct
In Python, comparing a string to an integer with == always returns False because they are different types. The exception is numeric types: int and float can compare, but string vs number is always False.
In weakly typed languages like JavaScript, '5' == 5 returns True because the string is coerced to a number. Python is strongly typed and does not perform implicit type conversion in comparisons, so beginners who have used other languages make this assumption.
Mistake
The 'in' operator is a relational operator.
Correct
The 'in' operator is a membership operator, not a relational operator. Relational operators (==, !=, <, >, <=, >=) compare values directly. The 'in' operator checks whether a value is present in a sequence (like a string, list, or tuple). For example, 'a' in 'apple' is True, but 'a' == 'apple' is False.
Both 'in' and relational operators return booleans and are often used in conditions, so beginners group them together. The exam expects you to know that 'in' is not part of the relational operator set defined in the objective.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Because Python is strongly typed and does not automatically convert between strings and integers when comparing. The integer 5 and the string '5' are different types, so == always returns False.
The = operator is used for assignment, like x = 5 (put the value 5 into the variable x). The == operator is used for equality comparison, like x == 5 (ask: is x equal to 5?). Using = in a condition like if x = 5: causes a SyntaxError.
It is operator chaining and is equivalent to (3 < 5) and (5 < 7). Python checks that 3 is less than 5 and 5 is less than 7. The result is True because both comparisons are true.
No, Python uses short-circuit evaluation. In an 'and' expression, if the left side is False, Python does not evaluate the right side. In an 'or' expression, if the left side is True, Python does not evaluate the right side. This can be used to avoid errors, like checking if a variable is not None before using it.
The 'not' operator first converts its operand to a boolean using Python's truthiness rules. Since 5 is truthy (not zero), not 5 becomes False. The 'not' operator always returns a boolean (True or False), not the original type.
Yes, Python allows comparison between numeric types (int and float). For example, 5 == 5.0 returns True because the values are numerically equal. However, comparing a string to a number always returns False.
From highest to lowest: not (highest), then relational operators (==, !=, <, >, <=, >=), then and, then or (lowest). If you are unsure, use parentheses to group conditions explicitly.
You've finished Logical and Relational Operators. Continue through the PCEP-30-02 study guide to build a complete picture of the exam.
Done with this chapter?