---
title: "Python list comprehensions: when to use them (and not)"
description: "List comprehensions turn a four-line loop into one readable line, until they don't. Learn the pattern, the filter form, and the point where a plain loop wins."
url: https://articles.sythra.ai/articles/python-list-comprehensions
slug: python-list-comprehensions
author: "vaibhavkothari"
author_url: https://articles.sythra.ai/writers/vaibhavkothari
date_published: 2026-11-12T21:11:00.153Z
date_modified: 2026-11-12T21:11:00.153Z
topics: ["Python", "Coding"]
reading_time_minutes: 5
publisher: "Sythra"
publisher_url: https://sythra.ai
access: free
language: en
---

# Python list comprehensions: when to use them (and not)

> List comprehensions turn a four-line loop into one readable line, until they don't. Learn the pattern, the filter form, and the point where a plain loop wins.

Source: https://articles.sythra.ai/articles/python-list-comprehensions · Author: vaibhavkothari · Published: 2026-11-12 · Reading time: 5 min · Topics: Python, Coding

Sooner or later you read someone's Python and meet a line like this:

```python
squares = [n * n for n in range(10)]
```

That is a list comprehension. It does exactly what a short `for` loop does, in a more compact shape. This guide shows how to read one, how to write one, and — just as important — when to leave them alone.

## The loop you already know

Start with a loop that builds a list:

```python
squares = []
for n in range(10):
    squares.append(n * n)

print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

Three things happen: make an empty list, loop, append each result. A comprehension collapses all three.

## The pattern

```python
[expression for item in iterable]
```

Read it left to right as a sentence: *"give me `expression`, for each `item` in `iterable`."*

```python
names = ["ada", "grace", "linus"]
upper = [name.upper() for name in names]
print(upper)  # ['ADA', 'GRACE', 'LINUS']
```

The part before `for` is what goes into the new list. The part after it is the loop. Nothing else is hidden.

## Add a filter with `if`

Put an `if` at the end to keep only some items:

```python
numbers = [3, 8, 1, 12, 7, 20]
big = [n for n in numbers if n > 5]
print(big)  # [8, 12, 7, 20]
```

The loop version is:

```python
big = []
for n in numbers:
    if n > 5:
        big.append(n)
```

You can transform and filter together:

```python
words = ["Python", "is", "a", "language"]
lengths = [len(w) for w in words if len(w) > 2]
print(lengths)  # [6, 8]
```

## If/else goes in front, not at the end

This is the part that trips beginners. A filter `if` goes **after** the loop. An `if/else` that chooses between two values goes **before** it, because it is part of the expression:

```python
scores = [45, 82, 67, 91]
labels = ["pass" if s >= 60 else "fail" for s in scores]
print(labels)  # ['fail', 'pass', 'pass', 'pass']
```

Memory trick: if there is an `else`, the whole `a if cond else b` is the *expression*, so it sits first.

## Real examples worth knowing

Clean up text read from a file:

```python
lines = ["  hello \n", "world\n", "  \n"]
clean = [line.strip() for line in lines if line.strip()]
print(clean)  # ['hello', 'world']
```

Pull one field out of a list of dictionaries:

```python
users = [
    {"name": "Ada", "age": 36},
    {"name": "Grace", "age": 45},
]
names = [u["name"] for u in users]
print(names)  # ['Ada', 'Grace']
```

Flatten a nested list with two loops (read the `for` parts in the same order you would write nested loops):

```python
grid = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in grid for x in row]
print(flat)  # [1, 2, 3, 4, 5, 6]
```

## Dictionary and set versions

The same idea works for dictionaries and sets using braces:

```python
word_lengths = {w: len(w) for w in ["apple", "fig", "banana"]}
print(word_lengths)  # {'apple': 5, 'fig': 3, 'banana': 6}

unique_lengths = {len(w) for w in ["apple", "fig", "pear"]}
print(unique_lengths)  # {3, 4, 5}
```

## When a comprehension is the wrong tool

Comprehensions are for *building a collection*. They get worse the moment you stretch them.

**Too much logic.** If you need a nested `if` inside a nested `for` with a function call, a loop is easier to read and debug:

```python
# Hard to scan
result = [transform(x) for row in data for x in row if x is not None and x > 0 and valid(x)]

# Easier
result = []
for row in data:
    for x in row:
        if x is None or x <= 0 or not valid(x):
            continue
        result.append(transform(x))
```

**Side effects.** Do not use a comprehension just to run something. This builds a throwaway list of `None` values:

```python
[print(n) for n in range(3)]   # works, but misleading
for n in range(3):             # say what you mean
    print(n)
```

**Huge data you only loop over once.** A comprehension builds the entire list in memory. If you only need to iterate, use a generator expression:

```python
total = sum(n * n for n in range(1_000_000))
```

No brackets, no million-item list.

## A simple rule of thumb

- One transformation, maybe one filter, fits on one line → **comprehension**
- You need to explain it with a comment → **loop**
- You are not building a list → **loop**

Readable beats clever. A teammate (or you in three months) should understand the line without pausing.

## Common mistakes

- **Putting `else` at the end.** `[x for x in items if x else 0]` is a syntax error. Move the conditional to the front.
- **Forgetting the loop variable leaks nowhere.** In Python 3 the variable inside a comprehension does not exist afterwards, unlike a normal `for` loop.
- **Modifying the list you are looping over.** Build a new list instead; that is what comprehensions are for.

## FAQ

### What is a list comprehension in Python?

A list comprehension is a compact syntax for creating a list from another sequence: `[expression for item in iterable if condition]`. It replaces a loop that creates an empty list and appends to it.

### Are list comprehensions faster than for loops?

Usually a little faster, because the append work happens in optimised internals. The difference rarely matters; choose based on readability first.

### Can I use if and else in a list comprehension?

Yes. Put the `if/else` before the `for`: `["yes" if n > 0 else "no" for n in numbers]`. A plain filter `if` goes after the `for`.

### What is the difference between a list comprehension and a generator expression?

A list comprehension builds the whole list in memory immediately. A generator expression uses parentheses and produces values one at a time, which saves memory when you only iterate once.

## Next reading on Sythra Articles

- [Seven Python patterns for ML notebooks](https://articles.sythra.ai/articles/seven-python-patterns-for-ml-notebooks)
- [Your first Python program: say hello in 5 minutes](https://articles.sythra.ai/articles/first-python-hello)
- [Clean a messy CSV with pandas](https://articles.sythra.ai/articles/clean-messy-csv-pandas)

## Glossary (terms defined in this article)
- **list comprehension** (basic) — A one-line way to build a new list by transforming or filtering another sequence
- **generator expression** (medium) — Like a list comprehension in parentheses; produces items one at a time instead of storing them all
