</>StackKit
</>StackKit

Developer tutorials & guides

Python List Comprehensions: Write Cleaner Code in One Line

Master Python list comprehensions — including nested comprehensions, conditions, dict comprehensions, and when NOT to use them for maximum clarity.

N

Nitheesh DR

Founder & Full-Stack Engineer

6 min read918 words
#python#list-comprehension#tutorial#clean-code

What Is a List Comprehension?

A list comprehension is a concise way to create a list from an iterable, combining a loop and optionally a condition into a single readable expression.

Basic syntax:

[expression for item in iterable]
[expression for item in iterable if condition]

Compare the two approaches:

# Traditional loop
squares = []
for n in range(10):
    squares.append(n ** 2)

# List comprehension
squares = [n ** 2 for n in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Same result, half the lines, more readable.


Basic Examples

Square numbers:

squares = [x ** 2 for x in range(1, 6)]
# [1, 4, 9, 16, 25]

Convert to uppercase:

fruits = ["apple", "banana", "cherry"]
upper = [f.upper() for f in fruits]
# ["APPLE", "BANANA", "CHERRY"]

Extract attribute from objects:

users = [{"name": "Alice", "age": 28}, {"name": "Bob", "age": 34}]
names = [u["name"] for u in users]
# ["Alice", "Bob"]

Adding a Condition (Filtering)

Add if at the end to filter elements:

# Only even numbers
evens = [n for n in range(20) if n % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# Words longer than 4 characters
words = ["cat", "elephant", "dog", "rhinoceros", "ox"]
long_words = [w for w in words if len(w) > 4]
# ["elephant", "rhinoceros"]

# Filter out None values
values = [1, None, 3, None, 5]
clean = [v for v in values if v is not None]
# [1, 3, 5]

if-else in the Expression

The if-else can go before the for to transform (not filter) elements:

# Label even/odd
labels = ["even" if n % 2 == 0 else "odd" for n in range(6)]
# ["even", "odd", "even", "odd", "even", "odd"]

# Clamp negatives to 0
nums = [-3, 5, -1, 8, -2, 4]
clamped = [n if n > 0 else 0 for n in nums]
# [0, 5, 0, 8, 0, 4]

Nested List Comprehensions

Flatten a 2D list:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Transpose a matrix:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(3)]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Nested comprehensions quickly become hard to read. If you need three levels of nesting, use a regular loop.


Dictionary Comprehensions

Same syntax, with {} and key: value:

# Square each number
squares = {n: n ** 2 for n in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Invert a dictionary
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
# {1: "a", 2: "b", 3: "c"}

# Filter a dict
prices = {"apple": 0.5, "truffle": 120.0, "milk": 1.2}
affordable = {k: v for k, v in prices.items() if v < 10}
# {"apple": 0.5, "milk": 1.2}

Set Comprehensions

Use {} without key-value pairs for a set (deduplicates automatically):

nums = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {n ** 2 for n in nums}
# {1, 4, 9, 16}

Generator Expressions

Replace [] with () to get a lazy generator instead of a full list in memory:

# List comprehension — builds full list in memory
total = sum([n ** 2 for n in range(1_000_000)])

# Generator expression — computes one at a time, much less memory
total = sum(n ** 2 for n in range(1_000_000))

When passing to a function that accepts an iterable (sum, max, any, all), use a generator expression.


Real-World Examples

Parse CSV-like data:

raw = ["Alice,28,Engineer", "Bob,34,Designer", "Carol,22,Developer"]
people = [line.split(",") for line in raw]
# [["Alice", "28", "Engineer"], ...]

people_dicts = [
    {"name": p[0], "age": int(p[1]), "role": p[2]}
    for p in people
]

Find all .py files:

import os
py_files = [f for f in os.listdir(".") if f.endswith(".py")]

Unique words in text:

text = "the cat sat on the mat the cat"
unique_words = list({word for word in text.split()})

When NOT to Use List Comprehensions

Comprehensions are for simple, readable transformations. Avoid them when:

  1. The logic requires multiple statements — use a regular loop
  2. Side effects are involved — printing, writing to files, modifying external state
  3. It spans more than 2 lines — readability drops sharply
  4. Nested 3+ levels deep — always reach for a regular loop
# Too complex — just use a loop
result = [
    process(item)
    for sublist in data
    for item in sublist
    if item.is_valid()
    if not item.is_archived()
]

Performance

List comprehensions are generally faster than equivalent for loops with append because Python optimizes them internally. But the difference is small and shouldn't be the reason you use them — readability is the real benefit.


Conclusion

List comprehensions are one of Python's most distinctive and practical features. They shine for transformations, filtering, and simple reshaping of data. The rule of thumb: if you can read it out loud naturally in one sentence, a comprehension is appropriate. If you're squinting at it, write a loop.

Tagged

#python#list-comprehension#tutorial#clean-code
N

Written by

Nitheesh DR

Founder & Full-Stack Engineer

Nitheesh is a full-stack software engineer based in Tamil Nadu, India, with hands-on experience building production SaaS applications using Next.js, TypeScript, React, Node.js, and cloud infrastructure. He founded StackKit to share the practical knowledge he uses every day — not just theory, but the real-world techniques that help developers ship better software faster.