In Python threads and dev chats, one of the most common logic questions pops up when writing config handling or fallbacks: why does this expression return a string instead of a boolean, and why did my function never run? That often traces back to Python’s or operator and how it evaluates expressions.
I keep seeing code like value = user_value or default_value. I thought or returns a boolean, but in Python it seems to return one of the operands. Also, I hear it uses short-circuit evaluation and has tricky precedence with and and with things like NumPy arrays. How does the or operator work in Python? What are common patterns and pitfalls I should know, and how should I write safer code with it?
Python’s or is a logical operator that returns one of its operands, not necessarily a boolean. It evaluates operands left to right and uses short-circuit evaluation.
- It returns the first truthy operand, if any.
- If all operands are falsy, it returns the last operand.
print(0 or "fallback") # "fallback" (0 is falsy)
print("hello" or "world") # "hello" (first operand is truthy)
print([] or {}) # {} (both falsy, returns last)Code language: PHP (php)
Truthy means any value that is not considered falsy. Falsy values include False, None, 0, empty sequences or collections like "", [], (), {}, and empty sets.
- If the left operand is truthy, Python does not evaluate the right operand.
- If the left operand is falsy, Python evaluates and returns the right operand.
def expensive():
print("expensive() called")
return "result"
print(True or expensive()) # True, function never called
print(False or expensive()) # "result", function is calledCode language: PHP (php)
and has higher precedence than or. So a or b and c is parsed as a or (b and c). When in doubt, add parentheses.
def expensive():
print("expensive() called")
return "result"
print(True or expensive()) # True, function never called
print(False or expensive()) # "result", function is calledCode language: PHP (php)
- Fallbacks:
config_value = user_valueordefault_value - Function results with fallback:
data = fetch() or compute_fallback() uses short-circuiting to avoid calling the fallback when not needed.
- Falsy vs None: if
0is a valid input,x = user_valueor10will replace0. Use explicit checks:x = 10 if user_value is None else user_value
- With collections and strings: empty values are falsy. If an empty string is a valid value, do not use
orfor defaults. - With NumPy or Pandas:
ordoes not compare arrays and will raise errors about ambiguous truth values. Use bitwise | orany()/all():
# Incorrect for arrays:
# if arr > 0 or arr < -1: ...
# Correct:
mask = (arr > 0) | (arr < -1)
if mask.any():
...
# Or for pure booleans:
if any(x > 0 for x in arr):
...Code language: PHP (php)
- Membership and precedence gotcha:
# Buggy intention: check if ext is "jpg" or "jpeg"
if ext == "jpg" or "jpeg":
pass # always truthy because "jpeg" is truthy
# Correct:
if ext in {"jpg", "jpeg"}:
...Code language: PHP (php)
Once you understand or, you can use it to set safe defaults when preparing media for upload or delivery. For example, pick a default output format and quality from environment variables, then upload and build a delivery URL.
import os
from cloudinary import config, uploader, CloudinaryImage
# Configure from env or use safe defaults with `or`
cloud_name = os.getenv("CLOUD_NAME") or "demo"
api_key = os.getenv("CLOUD_API_KEY") or "123456"
api_secret = os.getenv("CLOUD_API_SECRET") or "abcxyz"
config(cloud_name=cloud_name, api_key=api_key, api_secret=api_secret, secure=True)
# Choose format and quality with fallbacks
fmt = os.getenv("IMG_FORMAT") or "webp"
quality = int(os.getenv("IMG_QUALITY") or 80)
# Upload with options
res = uploader.upload(
"local-input.jpg",
folder="qa-or-operator",
format=fmt,
quality=quality
)
# Build a delivery URL with transformations
url = CloudinaryImage(res["public_id"]).build_url(
format=fmt,
transformation=[{"width": 800, "crop": "scale"}]
)
print(url)Code language: PHP (php)
You can also explore a catalog of handy utilities for quick conversions and testing at Cloudinary tools.
orreturns the first truthy operand, else the last one, and short-circuits.- Be careful when 0 or empty values are valid inputs. Prefer explicit None checks.
- With arrays, use
|,any(), orall()instead ofor. - Add parentheses to make precedence between
andandorunambiguous. - In real apps, or is great for fallbacks and defaults, including media workflows that later leverage Cloudinary for upload and delivery.
Python’s or returns operands, not booleans. It short-circuits, so the right side may never run. Use it for lightweight defaults and fallbacks, but avoid it when 0 or empty values are valid. For arrays, prefer | or any(). In media pipelines, or helps set safe defaults before you upload or transform assets with services like Cloudinary.
Ready to streamline your media workflow with smart defaults and powerful delivery? Sign up for Cloudinary and start building today.