How to use 'or' in Python

Learn how to use the 'or' operator in Python. Explore different methods, real-world applications, and tips for debugging common errors.

How to use 'or' in Python
Published on: 
Fri
Feb 6, 2026
Updated on: 
Tue
Feb 10, 2026
The Replit Team Logo Image
The Replit Team

Python's or operator is a versatile tool to control program flow and evaluate conditions. It's essential to write flexible code, handle default values, and simplify complex logic.

You will learn techniques to use or beyond simple booleans, with real-world applications and debugging advice. These tips help you write cleaner and more efficient Python code.

Basic usage of the or operator

result1 = True or False
result2 = False or False
print(f"True or False: {result1}")
print(f"False or False: {result2}")--OUTPUT--True or False: True
False or False: False

The or operator uses short-circuit evaluation, meaning it stops as soon as it finds a truthy value. This makes your code more efficient because the interpreter doesn't do unnecessary work.

  • In True or False, Python sees True and immediately returns it without checking the second operand.
  • The expression only evaluates to False if all operands are falsy, as demonstrated by False or False.

This lazy evaluation is a key principle that you can use for more than just boolean checks.

Using the or operator with variables and conditions

You can extend this lazy evaluation principle to handle complex conditional logic and variable comparisons, which is where the or operator truly shines.

Using or with variable comparisons

x = 5
y = 10
is_valid = x > 10 or y > 8
print(f"x > 10 or y > 8: {is_valid}")
condition = x < 3 or y < 3
print(f"x < 3 or y < 3: {condition}")--OUTPUT--x > 10 or y > 8: True
x < 3 or y < 3: False

The or operator is perfect for combining multiple comparisons into a single check. It stops and returns True as soon as it finds a condition that passes, making your logic more concise.

  • The expression x > 10 or y > 8 evaluates to True because while the first condition is false, the second one (y > 8) is true.
  • Conversely, x < 3 or y < 3 results in False since both comparisons fail.

Using or in conditional statements

age = 25
income = 40000

if age > 18 or income > 50000:
print("Eligible for premium membership")
else:
print("Not eligible for premium membership")--OUTPUT--Eligible for premium membership

The or operator is powerful inside if statements for creating flexible eligibility rules. It lets a block of code run if any one of several conditions is met, making your logic less restrictive.

  • In this example, the condition age > 18 evaluates to true. The or operator immediately stops and executes the if block without ever checking the income > 50000 part.

This is perfect for scenarios where multiple independent factors can qualify a user for something, like membership or access.

Short-circuit evaluation with or

def check(message, return_value):
print(f"Checking: {message}")
return return_value

result = check("First condition", True) or check("Second condition", False)
print(f"Result: {result}")--OUTPUT--Checking: First condition
Result: True

This example is a great illustration of short-circuiting in action. The check() function prints a message to let you know it's running. Since the first call, check("First condition", True), returns True, the or operator stops right there and returns the result immediately.

  • The key takeaway is that the second function, check("Second condition", False), is never executed. You can confirm this because its message doesn't appear in the output.
  • This behavior is useful for avoiding expensive operations, like network requests or complex calculations, if they aren't needed.

Advanced uses of the or operator

Building on its short-circuiting behavior, the or operator unlocks more advanced patterns for setting default values and combining complex logical checks.

Combining or with other logical operators

a, b, c = True, False, True
# Combining and, or, and not
result1 = (a and b) or (not b and c)
result2 = a and (b or c)
print(f"(True and False) or (not False and True): {result1}")
print(f"True and (False or True): {result2}")--OUTPUT--(True and False) or (not False and True): True
True and (False or True): True

You can create sophisticated logical checks by combining or with other operators like and and not. Parentheses are crucial here because they dictate the order of evaluation, ensuring your logic runs exactly as you intend. This lets you group conditions to build complex but readable rules.

  • In the first result, (a and b) is False, but (not b and c) is True. The or operator then returns True.
  • For the second result, the inner expression (b or c) evaluates to True first. The logic simplifies to a and True, which also results in True.

The or operator with different data types

# or returns the first truthy value or the last value
result1 = 0 or "" or [] or "Hello"
result2 = 42 or "Python"
result3 = "" or 0 or None
print(result1, result2, result3)--OUTPUT--Hello 42 None

The or operator returns the first truthy value it encounters, not just a boolean. This is a powerful feature for setting defaults. In Python, values like 0, empty strings (""), empty lists ([]), and None are considered "falsy."

  • The expression 0 or "" or [] or "Hello" evaluates to "Hello" because it's the first truthy item in the chain.
  • Similarly, 42 or "Python" immediately returns 42.
  • If all operands are falsy, as in "" or 0 or None, the operator simply returns the last value, which is None.

Using or for default values

# Setting default values with or
user_name = ""
display_name = user_name or "Guest"

config = {"timeout": 0}
timeout = config.get("timeout") or 30
print(f"Welcome, {display_name}! Timeout: {timeout}s")--OUTPUT--Welcome, Guest! Timeout: 30s

This pattern is a Pythonic shortcut for setting default values. The or operator assigns the first truthy value it finds, making your code more compact.

  • In the first case, user_name is an empty string, which is falsy. As a result, display_name defaults to "Guest".
  • The second example highlights a common gotcha. Since config.get("timeout") returns 0 (another falsy value), the timeout is set to 30. This is great for defaults, but be careful when 0 is a valid, intended value.

Move faster with Replit

Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.

For the logical patterns we've explored with the or operator, Replit Agent can turn them into production-ready tools:

  • Build a user access control system that grants permissions if a user has either admin rights or a premium subscription.
  • Create a configuration loader that sets default application settings, like a timeout or theme, when a user's preferences are missing or invalid.
  • Deploy a data cleaning utility that processes user-submitted forms, automatically populating empty fields with default values like "Guest" or "N/A".

Describe your app idea, and Replit Agent writes the code, tests it, and fixes issues automatically, all in your browser.

Common errors and challenges

The or operator is powerful, but a few common pitfalls can lead to unexpected behavior if you're not careful.

  • Fixing operator precedence with or: A frequent source of bugs is forgetting that the and operator has higher precedence than or. For example, in an expression like a or b and c, Python evaluates b and c first. To control the order of operations and avoid ambiguity, always group your conditions with parentheses, such as (a or b) and c.
  • Using or versus the in operator: It’s a classic mistake to check for multiple values with a chain of or statements like if fruit == 'apple' or 'orange'. This doesn't work because the non-empty string 'orange' is always truthy, making the condition always true. The correct, more readable approach is to use the in operator: if fruit in ('apple', 'orange').
  • Handling falsy values with or: Using or to set a default can backfire when a falsy value like 0 or an empty string is a valid input. An expression like setting = config_value or 30 would incorrectly override a legitimate config_value of 0. In these cases, it's safer to be explicit with a check like if setting is None: to avoid discarding valid data.

Fixing operator precedence with or

Operator precedence often causes logical bugs, but a similar issue arises from how Python evaluates chained or comparisons. It doesn't check one variable against multiple values; it checks each item's truthiness. See how this plays out in the code below.

x = 5

# Intended: Check if x equals 5, 10, or 15
if x == 5 or 10 or 15:
print("x is either 5, 10, or 15")
else:
print("x is not 5, 10, or 15")

The condition x == 5 or 10 or 15 always passes because Python evaluates the truthiness of 10, a non-zero number. The or operator short-circuits, making the if block run unexpectedly. The correct approach is more direct.

x = 5

# Correct way to check if x equals any of these values
if x == 5 or x == 10 or x == 15:
print("x is either 5, 10, or 15")
else:
print("x is not 5, 10, or 15")

The fix is to compare the variable in each part of the condition explicitly. The expression x == 5 or x == 10 or x == 15 works because it forces Python to evaluate each comparison separately. This is the correct way to check if a variable matches one of several values. The original code fails because a non-zero number like 10 is always truthy, causing the or operator to short-circuit and return a misleading result.

Using or versus the in operator

A common mistake is using the or operator to check if a variable matches one of several values. An expression like fruit == "apple" or "banana" won't work as expected because a non-empty string is always truthy. The code below demonstrates this pitfall.

# Trying to check if fruit is apple, banana, or orange
fruit = "grape"
if fruit == "apple" or "banana" or "orange":
print(f"{fruit} is in our basket")
else:
print(f"{fruit} is not in our basket")

The condition incorrectly passes because Python checks the truthiness of the string "banana" instead of comparing it to fruit. The or operator then short-circuits. The correct approach is far more readable—see it in action below.

# Correct way to check membership
fruit = "grape"
if fruit in ["apple", "banana", "orange"]:
print(f"{fruit} is in our basket")
else:
print(f"{fruit} is not in our basket")

The correct solution uses the in operator, which is designed to check for membership in a collection. It's the Pythonic way to see if a variable matches any value in a list, tuple, or other iterable.

  • The expression fruit in ["apple", "banana", "orange"] clearly checks if the fruit is in the list.
  • This avoids the common bug where or "banana" is always truthy, making your logic reliable and easy to read.

Handling falsy values with or

While the or operator is handy for setting defaults, it doesn't distinguish between a missing value and a "falsy" one like 0. This can cause problems when 0 is a legitimate setting, as it will be incorrectly overridden. See how this plays out below.

# Setting default values with or
user_settings = {"volume": 0, "brightness": 50}
volume = user_settings.get("volume") or 100
brightness = user_settings.get("brightness") or 75

print(f"Volume: {volume}, Brightness: {brightness}")

The user's volume setting of 0 is incorrectly replaced with 100 because 0 is a falsy value, causing the or operator to discard it. The following code demonstrates a safer way to handle this scenario.

# Correctly handling falsy values that might be valid
user_settings = {"volume": 0, "brightness": 50}
volume = user_settings.get("volume") if "volume" in user_settings else 100
brightness = user_settings.get("brightness") if "brightness" in user_settings else 75

print(f"Volume: {volume}, Brightness: {brightness}")

The fix is to check for the key's presence instead of its value's truthiness. A conditional expression like ... if "volume" in user_settings else ... explicitly verifies that the key exists, correctly preserving the intended volume of 0.

  • This pattern is crucial when falsy values like 0, False, or an empty string are valid data you need to keep. It prevents them from being accidentally replaced by a default.

Real-world applications

Beyond avoiding errors, the or operator is a powerful tool for everyday tasks like validating forms and setting up configuration fallbacks.

Form validation with the or operator

By combining the or and not operators, you can create a simple check to ensure all required form fields have been filled.

username = "john_doe"
email = "" # Empty email
password = "password123"

is_invalid = not username or not email or not password
if is_invalid:
print("Form submission failed: All fields are required")
else:
print("Form submitted successfully")

This logic hinges on Python's concept of truthiness. The not operator inverts the boolean value of each field, so an empty string like email becomes True while non-empty ones become False.

  • The expression is_invalid becomes True as soon as the or operator encounters the not email condition.
  • Because of short-circuiting, the password field is never even checked, making the validation efficient.

This pattern quickly flags a form as invalid if even one required field is missing, triggering the failure message.

Using or for configuration fallbacks

The or operator is also great for creating a configuration hierarchy, allowing your application to check for a setting in an environment variable before falling back to a config file or a default value.

# Simulate different config sources
env_vars = {"DEBUG": "True"} # Environment variables
config_file = {"app.name": "MyApp", "app.timeout": 30} # Config file

app_name = env_vars.get("APP_NAME") or config_file.get("app.name") or "DefaultApp"
timeout = env_vars.get("TIMEOUT") or config_file.get("app.timeout") or 60
debug = env_vars.get("DEBUG") == "True" or config_file.get("app.debug") or False

print(f"App: {app_name}, Timeout: {timeout}, Debug: {debug}")

This code sets configuration values with a clear order of preference. The or operator chains multiple sources, selecting the first available truthy value it finds. This pattern is great for creating flexible application settings.

  • For app_name, since env_vars.get("APP_NAME") is None, the code uses the value from config_file.
  • The timeout is also set from config_file for the same reason.
  • The debug variable requires a specific check, == "True", because environment variables are always strings. This ensures you get a boolean True instead of a truthy string.

Get started with Replit

Put your knowledge of the or operator into practice. Describe your idea to Replit Agent, like "build a discount calculator for new users or orders over $50" or "create a server monitor that alerts on high CPU or low memory."

Replit Agent writes the code, tests for errors, and deploys your application directly from your browser. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.