Nested Comprehensions in Python
Nested Comprehensions in Python
When engineering applications that handle tabular records, image pixel arrays, geographical coordinates, or hierarchical JSON datasets, you constantly work with nested data structures.
A Nested Comprehension is a comprehension contained inside another comprehension. It allows you to generate multi-dimensional grids, transpose matrices, and transform deeply nested dictionaries in declarative, high-speed Python.
Real-World Analogy: Indian Railways Multi-Tier Coach Seating Chart
Imagine the reservation chart for an Indian Railways 3-Tier AC coach (B1):
+-------------------------------------------------------------------------+ | RAILWAY COACH BERTH MATRIX GENERATOR | +-------------------------------------------------------------------------+ | | | Outer Comprehension: [ Coach Compartments 1 to 8 ] | | │ | | ▼ | | Inner Comprehension: [ Berths inside Compartment: Lower, Middle, Upper]| | │ | | ▼ | | Resulting 2D Structure: | | [ | | ["Bay 1 - Lower", "Bay 1 - Middle", "Bay 1 - Upper"], | | ["Bay 2 - Lower", "Bay 2 - Middle", "Bay 2 - Upper"], | | ... | | ] | +-------------------------------------------------------------------------+
- Flattening: If the ticket collector wants a single flat scroll of all 72 passengers regardless of compartment, you use a multi-loop flattening comprehension.
- Nested Preservation: If the display board on the platform needs to show bays row-by-row, you nest an inner comprehension inside an outer comprehension.
Critical Distinction: Flattening vs Preserving Structure
Developers often confuse two completely different syntax patterns:
+------------------------------------+------------------------------------+ | 1. Flattening Comprehension | 2. True Nested Comprehension | | (Results in 1D flat list) | (Results in 2D nested list) | +------------------------------------+------------------------------------+ | [val for row in grid for val in r]| [[val for val in row] for row in g| | | | | Output: [1, 2, 3, 4] | Output: [[1, 2], [3, 4]] | +------------------------------------+------------------------------------+
The Ordering Rule:
- 1In Flattening (
[x for sublist in list for x in sublist]):
The loops read left-to-right exactly like nested for statements: outer first, inner second.
- 1In True Nested Comprehensions (
[[expr for inner] for outer]):
The outer comprehension runs the outer loop, and its expression is an entire enclosed inner comprehension.
Comprehensive Code Examples
1. Generating a 2D Seating Grid
Expected Output:
2. Matrix Transposition (Swapping Rows and Columns)
Transposing a matrix swaps rows into columns ($M_{ij} \to M_{ji}$). This is a fundamental operation in numerical computing and data analysis.
Expected Output:
3. Nested Dictionary Comprehensions
Hierarchical corporate structures often store departments, employees, and salaries. Nested dictionary comprehensions transform multi-tier mappings effortlessly:
Expected Output:
4. Selective Multi-Condition Filtering in Nested Lists
Expected Output:
The Readability Rule: When NOT to Nest Comprehensions
While Python allows arbitrary nesting, deeply nested comprehensions quickly become unreadable write-only code (often termed "comprehension pyramids").
for loops. Readability always counts more than terseness.Best Practices & Comparison: Do's and Don'ts
| Practice | Bad / Unreadable Pattern | Recommended Gold Standard |
|---|---|---|
| Grid Generation | [[x for x in r] for r in [[y for y in z] for z in w]] (3+ levels) | Max 2 levels; refactor deeper levels into generator functions |
| Transposition | Manual indexed nested loops with temporary arrays | [[row[i] for row in matrix] for i in range(cols)] |
| Flattening Syntax | Putting inner loop before outer loop (causes SyntaxError) | Order for loops left-to-right matching standard nested loop order |
| Formatting | Writing nested comprehensions on one giant 150-char line | Format across multiple indented lines for visual hierarchy |
Quick Revision Summary Cheat Sheet
- 2D Grid Generation:
[[f(x, y) for y in col_iter] for x in row_iter] - 1D Flattening:
[item for sublist in matrix for item in sublist] - Transposition:
[[row[i] for row in matrix] for i in range(len(matrix[0]))] - Nested Dicts:
{outer_k: {inner_k: expr for inner_k, v in inner_d.items()} for outer_k, inner_d in d.items()} - Evaluation Order: Outer comprehension controls outer dimensions; inner comprehension creates each row or nested value.
Multiple Choice Questions
1. What is the difference between [x for row in matrix for x in row] and [[x for x in row] for row in matrix]?
A. The first produces a 1D flattened list, whereas the second produces a 2D nested list B. The first produces a dictionary, whereas the second produces a tuple C. The first is invalid syntax that causes a SyntaxError D. Both produce identical 2D lists Answer: A Explanation: The first expression flattens the matrix into a single 1D list by chaining two for clauses. The second expression nests an inner list comprehension [x for x in row] inside an outer list comprehension, preserving the 2D row-by-row structure.
2. What will the following expression evaluate to?
A. [[1, 2], [3, 4]] B. [[1, 3], [2, 4]] C. [1, 2, 3, 4] D. [[4, 3], [2, 1]] Answer: B Explanation: For i = 0, it gathers column 0 from each row: [1, 3]. For i = 1, it gathers column 1 from each row: [2, 4]. The resulting transposed matrix is [[1, 3], [2, 4]].
3. Given matrix = [[10, 20], [30, 40], [50, 60]], what is the order of execution for [val for row in matrix for val in row]?
A. The inner loop for val in row executes before the matrix is accessed B. The outer loop for row in matrix iterates first, and for each row, the inner loop for val in row executes C. Python evaluates elements randomly in parallel D. Elements are evaluated from highest value to lowest value Answer: B Explanation: Multi-loop comprehensions strictly follow left-to-right evaluation order, mirroring the exact structure of standard nested for statements.
4. What is the primary software engineering concern with deeply nested comprehensions (3 or more levels)?
A. CPython refuses to compile more than 2 loops B. Code readability deteriorates rapidly, violating Python's core design philosophy (PEP 20: "Readability counts") C. They consume 100 times more GPU power D. They automatically convert integers into strings Answer: B Explanation: While Python syntactically allows deeply nested comprehensions, code comprehension and maintainability suffer drastically. Industry standard guidelines recommend breaking 3+ level comprehensions into clear functions or traditional loops.
5. What does the following nested dictionary comprehension output?
A. 2 B. 1 C. 0 D. KeyError Answer: B Explanation: In "Batch-B", Rohan scored 65 (passed) and Kavita scored 45 (filtered out because sc < 50). Only Rohan remains in passed["Batch-B"], so its length is 1.
Practice Challenge
Scenario: Indian Railway Berth Allocation Matrix
In Indian Railways Sleeper coaches, each compartment bay contains 6 berths numbered across 3 tiers:
- Lower Berth (LB): Seat numbers where
n % 3 == 1 - Middle Berth (MB): Seat numbers where
n % 3 == 2 - Upper Berth (UB): Seat numbers where
n % 3 == 0
Given 3 consecutive bays with seat numbers 1 to 18:
- 1Divide seats into 3 bays of 6 seats each using a nested comprehension:
- Bay 1: Seats 1 to 6
- Bay 2: Seats 7 to 12
- Bay 3: Seats 13 to 18
- 1For each seat number, attach its berth abbreviation (
"LB","MB", or"UB"). - 2Print the final 2D coach layout showing each bay row-by-row.
Starter Code
Complete Solution
Expected Output
Project: Data Filtering with Comprehensions
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Dictionary Comprehensions | Project: Data Filtering with Comprehensions |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.