Python
List Comprehensions
Nested Lists
Data Processing
Programming Tips

How can I use list comprehensions to process a nested list?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

List comprehensions are one of the cleanest ways to transform nested data in Python. The main idea is simple: place the expression first, then write the for clauses in the same order you would nest loops.

Flattening a nested list

The most common task is flattening a list of lists into a single list. If you would normally write an outer loop over rows and an inner loop over items, the comprehension follows that same order.

python
1rows = [[1, 2, 3], [4, 5], [6, 7, 8]]
2
3flat = [item for row in rows for item in row]
4
5print(flat)

This produces one list containing every element from every inner list. Read it left to right as "build item for each row in rows, and for each item in that row." The order of the for clauses matters. If you reverse them, the comprehension will not work because row would not exist yet.

Filtering and transforming in one pass

Comprehensions become more useful when you filter and transform at the same time. That lets you express a complete data-processing step without a temporary list.

python
1rows = [[1, 2, 3], [4, 5], [6, 7, 8]]
2
3even_squares = [item * item for row in rows for item in row if item % 2 == 0]
4
5print(even_squares)

This reads as "take each item from each row, keep only even values, and square them." It is concise, but still readable because the transformation is small and the condition is local to the item.

If the condition applies to the inner list instead of the individual value, move the if next to the relevant for clause. The comprehension should mirror the structure of the logic you would otherwise write as loops.

Preserving the nested structure

Not every nested-list task should flatten the data. Sometimes you want to keep the outer shape and transform each inner list independently. In that case, use a comprehension inside another comprehension.

python
1matrix = [[1, 2, 3], [4, 5, 6]]
2
3shifted = [[value + 10 for value in row] for row in matrix]
4filtered = [[value for value in row if value % 2 == 1] for row in matrix]
5
6print(shifted)
7print(filtered)

The outer comprehension creates one result row for each input row. The inner comprehension decides what belongs inside that row. This pattern is useful for matrix-like data, tokenized text, or grouped measurements where group boundaries still matter.

Combining nested data safely

Nested lists are not always regular. Some rows are empty, some may contain strings, and some may be different lengths. Comprehensions handle irregular shape well as long as you write the condition at the right level.

python
1records = [["alice", 91], [], ["bob", 84], ["carol", 95]]
2
3names = [row[0] for row in records if row]
4top_scores = [row[1] for row in records if row and row[1] >= 90]
5
6print(names)
7print(top_scores)

The if row guard prevents an index error on empty rows. That is a good example of a comprehension staying compact without becoming unsafe.

When a loop is clearer

List comprehensions are excellent for straightforward mapping and filtering. They are a poor choice when the logic includes multiple branches, state updates, error handling, or side effects. If the expression becomes hard to scan, a normal for loop is the better tool.

As a practical rule, if you cannot explain the comprehension in one sentence, it is probably too dense. Readability matters more than saving a few lines.

Common Pitfalls

  • Reversing the order of the for clauses. Write them in the same order as nested loops.
  • Using a comprehension for side effects such as logging or mutation. A plain loop is clearer for that job.
  • Forgetting that strings are iterable. Flattening a list that contains strings may split them into characters.
  • Writing a very deep comprehension when the logic has multiple conditions and branches. That usually hurts readability.
  • Indexing nested rows without checking shape first. Guards such as if row prevent errors with empty inner lists.

Summary

  • Use [item for row in rows for item in row] to flatten a list of lists.
  • Add an if clause to filter values and keep the transformation in one pass.
  • Nest comprehensions when you want to preserve the outer structure.
  • Keep the clause order aligned with the loop order you would write by hand.
  • Switch back to explicit loops when the expression stops being easy to read.

Course illustration
Course illustration

All Rights Reserved.