Conditionals in List Comprehensions

Data Science Tool Box Mar 18, 2026

Conditionals in List Comprehensions

Adding conditionals (if statements) inside list comprehensions is one of the most powerful and frequently used patterns in data science. It allows you to filter and transform data in a single, clean, and efficient line of code.

TL;DR — Two Types of Conditionals

  • Filtering: [expr for item in iterable if condition]
  • Conditional Expression: [expr_if_true if condition else expr_if_false for item in iterable]

1. Filtering with if (Most Common)

scores = [85, 92, 78, 95, 88, 76, 91, 65]

# Keep only high scores
high_scores = [score for score in scores if score >= 90]

# Multiple conditions
valid_high = [score for score in scores if score >= 90 and score <= 100]

print(high_scores)

2. Conditional Expressions (if-else inside)

scores = [85, 92, 78, 95, 65]

# Categorize scores
categories = ["High" if s >= 90 else "Medium" if s >= 75 else "Low" for s in scores]

print(categories)

3. Real-World Data Science Examples

import pandas as pd

# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
    "order_id": range(1001, 1001 + n),
    "order_date": pd.date_range("2026-01-01", periods=n, freq="3D"),
    "customer_id": rng.integers(101, 121, n),
    "customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
    "product_id": rng.integers(1, 9, n),
    "region": rng.choice(["North", "South", "East", "West"], n),
    "category": rng.choice(["Electronics", "Computers", "Books", "Home"], n),
    "payment_method": rng.choice(["card", "cash", "wallet"], n),
    "segment": rng.choice(["consumer", "business"], n),
    "quantity": rng.integers(1, 6, n),
    "amount": rng.uniform(50, 2500, n).round(2),
    "discount": rng.choice([0.0, 0.05, 0.1, 0.2], n),
}).assign(
    price=lambda d: (d["amount"] / d["quantity"]).round(2),
    profit=lambda d: (d["amount"] * rng.uniform(0.05, 0.3, n)).round(2),
).assign(
    ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
    status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)

df = pd.read_csv("sales_data.csv")

# Example 1: Create new column with conditional logic
df["sales_category"] = [
    "High Value" if amount > 1500 
    else "Medium" if amount > 800 
    else "Low" 
    for amount in df["amount"]
]

# Example 2: Filter and clean in one step
clean_amounts = [
    round(amount, 2) 
    for amount in df["amount"] 
    if pd.notna(amount) and amount > 0
]

# Example 3: Feature engineering with conditions
features = [
    f"{col}_log" if "amount" in col or "profit" in col else col 
    for col in df.columns
]

4. Best Practices in 2026

  • Use simple if at the end for filtering
  • Use if-else inside the expression for value transformation
  • Keep comprehensions readable — avoid more than one nested conditional
  • For very complex logic, switch to a traditional for loop
  • Combine with enumerate() or zip() when needed

Filtering versus Choosing

Conditions can appear in two places in a comprehension. An if after the for clause filters: items that fail are left out, so the result can be shorter than the input. An if-else before the for clause chooses a value for every item, so the result always has the same length.

You can combine both: filter first with a trailing if, then choose a label with an if-else expression. Keep each condition simple; move complicated rules into a small named function and call it from the comprehension.

For pandas columns, np.where and np.select are the vectorised equivalents and are much faster on large data.

Worked Example: Both Kinds of Condition

We filter, label and combine conditions on a list of order values, then do the same with NumPy.

import numpy as np

amounts = [120, 45, 980, 0, 310]

nonzero = [a for a in amounts if a > 0]
labels = ["big" if a >= 300 else "small" for a in amounts]
big_nonzero = ["big" if a >= 300 else "small" for a in amounts if a > 0]

print(nonzero)
print(labels)
print(big_nonzero)

def tier(a):
    if a >= 500:
        return "gold"
    return "silver" if a >= 100 else "bronze"

print([tier(a) for a in amounts])
print(np.where(np.array(amounts) >= 300, "big", "small").tolist())

The filtered list has four items, the labelled list keeps all five, and the combined version labels only the non-zero amounts. The helper function keeps a three-way rule readable inside the comprehension.

Common Mistakes

  • Putting if-else after the for clause.
  • Expecting a trailing if to keep all items.
  • Chaining many conditional expressions in one line.
  • Using comprehensions on large numeric columns instead of np.where.

Quick Summary

  • Trailing if filters items.
  • Leading if-else chooses a value per item.
  • Move complex rules into a function.
  • Use np.where or np.select for arrays.

Conclusion

Conditionals inside list comprehensions make data cleaning, filtering, and feature engineering extremely concise and Pythonic. In 2026, mastering the difference between filtering (if at the end) and conditional expressions (if-else inside) is essential for writing clean, efficient data science code. Use them liberally for simple cases, but fall back to explicit loops when the logic becomes too complex.

Next steps:

  • Review your data cleaning and feature engineering code — replace multiple for loops + append() with conditional list comprehensions where appropriate

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices