Skip to contentSkip to navigation
Module 03 / Data StructuresLesson 6 of 6 (Module Capstone)Intermediate15 min read

List Comprehensions

Construct declarative list, set, and dictionary comprehensions. Contrast filtering predicates with ternary mapping, flatten multidimensional matrices, avoid 2D reference aliasing traps, and explore PEP 709 bytecode inlining.

01

Foundations & Core Architecture

3-Tier Learning Ladder
🟢 Level 1: Filtering & Mapping→🟡 Level 2: Inverted Index & Sets→🔴 Level 3: Matrix Transposition & Joins

Why Master Python Comprehensions?

Comprehensions are widely considered one of Python's most defining syntactic superpowers. They replace noisy, multi-line accumulator loops with concise, expressive, and declarative mathematical transformations. Beyond clean syntax, comprehensions in modern CPython are significantly faster than traditional `.append()` loops because the iteration loop and buffer pre-allocation run entirely within optimized C bytecode without the overhead of repeated method lookups. In Python 3.12 (via PEP 709), comprehensions are inlined directly into their parent bytecode frames, eliminating function call overhead entirely. Comprehensions are ubiquitous across production Python—from data manipulation in Pandas and Django queryset transformations to high-throughput API payload shaping. Essential for Data Scientists, Backend Engineers, and Systems Programmers.

1. Set-Builder Mathematical Notation

Directly translates mathematical set-builder logic into concise Python syntax: [expr for item in iterable if condition] replaces boilerplate accumulator lists and explicit loop frames.

2. The Placement Rule

Filtering conditions belong at the END ([x for x in data if cond]), while conditional value transformations belong at the BEGINNING ([x if cond else y for x in data]).

3. The Four Flavors

Python offers [...] for ordered lists, {...} for deduplicating sets, {k: v...} for key-value dictionaries, and (...) for lazy generator expressions with $O(1)$ memory.

4. PEP 709 Inlined Bytecode

Python 3.12 inlines list, set, and dict comprehensions directly into the caller's bytecode, eliminating function call frame allocation overhead while strictly isolating iteration scope.

Curriculum Learning Objectives

  • Construct idiomatic list, set, and dictionary comprehensions to transform and filter data structures declaratively.
  • Differentiate between filtering clauses (trailing 'if') and conditional value expressions (inline ternary 'x if cond else y').
  • Flatten and transform multidimensional matrices and nested collections using multi-level for clauses.
  • Initialize multi-dimensional data structures safely without introducing shared reference aliasing bugs.
  • Compare eager list comprehensions with lazy generator expressions in terms of peak memory usage and pipeline streaming.
  • Analyze CPython's PEP 709 inlined comprehension architecture, bytecode execution, and variable scope isolation.
02

Syntax Anatomy & The Placement Rule

The 3-Part Comprehension Equation

[  output_expression   FOR  item  IN  iterable   IF  filter_condition  ]
   ^^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^
   1. Transform/Map         2. Traversal Loop         3. Optional Filter
1. Trailing Filter (Discarding):

[x for x in nums if x % 2 == 0] — The if evaluates per item. If false, the item is dropped completely. Output length is $\le$ input length.

2. Leading Ternary (Transforming):

['even' if x % 2 == 0 else 'odd' for x in nums] — The ternary computes a substitute for every single element. Output length equals input length.

List Comprehension: [...]Ordered / Mutable

Constructs a newly allocated, indexed mutable Python list.

[x * 2 for x in [1, 2, 3]]
→ [2, 4, 6]
Set Comprehension: {...}Deduplicated

Builds a hash-backed set, enforcing uniqueness automatically.

{len(w) for w in ["cat", "dog", "horse"]}
→ {3, 5}
Dict Comprehension: {k: v...}Key-Value Mapping

Constructs an associative hash map. Requires explicit colon k: v pair.

{x: x**2 for x in (1, 2, 3)}
→ {1: 1, 2: 4, 3: 9}
Generator Expression: (...)Lazy / O(1) RAM

Evaluates on demand using iterator protocol. Zero eager allocation.

sum(x * x for x in range(1_000_000))
→ 333332833333500000
03

Execution Architecture: PEP 709 & Memory Profiles

PEP 709: Inlined Comprehensions in Modern CPython (Python 3.12+)

Historically, CPython compiled list comprehensions by generating an anonymous internal nested function (visible as <listcomp> in tracebacks). While this guaranteed that iteration targets like x would not leak into the surrounding scope, calling a new function frame incurred a ~100ns penalty. In Python 3.12 (PEP 709), comprehensions are inlined directly into the caller's bytecode, delivering up to 2x speedups without leaking local variables.

Visual Architecture: Data Flow in Comprehensions

 Source Iterable: [1, 2, 3, 4, 5, 6]
         |
    [IF Filter: x % 2 == 0] ===(Discard 1, 3, 5)===> [2, 4, 6]
         |
    [Output Expression: x * 10]
         |
    +----+------------------------------------------------+
    |                                                     |
    v                                                     v
List Comp: [x*10 ...]       Generator Expression: (x*10 ...)
Allocates complete array    Produces lazy generator iterator
[20, 40, 60] in RAM         Calculates next value on demand:
O(N) Peak Memory            O(1) Peak Memory

Memory Aliasing Bug: Why [[0]*3]*3 Silently Corrupts Grids

Writing grid = [[0] * 3] * 3 creates an outer list containing 3 pointers pointing to the exact same inner list in RAM. Modifying grid[0][0] = 99 mutates every row because there is only one list object!

# Always use nested comprehensions for independent row memory allocations:
grid = [[0 for _ in range(cols)] for _ in range(rows)]
04

Comprehension Flavors Comparison Matrix

FlavorSyntax TemplateResult TypeMemory CostDuplicate HandlingPrimary Engineering Use Case
List Comp[x for x in seq]listO(N) EagerPreservedIndexed collections, UI lists, sequential data
Set Comp{x for x in seq}setO(U) EagerDeduplicatedUnique tag extractors, vocabulary building
Dict Comp{k: v for k, v in seq}dictO(K) EagerOverwrittenO(1) lookup tables, indexing, record transformations
Generator Exp(x for x in seq)generatorO(1) LazyPreservedStreaming huge datasets, single-pass pipeline reductions
05

Interactive Syntax Reference & Sandbox

Basic Expression Mapping

Calculates a transformation for each item in the collection.

Basic list comprehension
squares = [x * x for x in range(6)]
print("Squares:", squares)

words = ["python", "data", "structures"]
uppercased = [w.upper() for w in words]
print("Uppercased:", uppercased)
06

Tiered Code Walkthroughs (Worked Examples)

Level 1 · Foundation

E-Commerce Catalog Filtering & Price Markdown Engine

Engineering Requirement

Given an inventory list of product dictionaries, extract all in-stock electronic goods, calculate a 10% promotional markdown price rounded to 2 decimal places, and build a quick stock-lookup dictionary mapping product IDs to their current inventory count.

Solution Implementation: E-Commerce Catalog Filtering & Price Markdown Engine
inventory = [
    {"id": "P101", "name": "Wireless Mouse", "price": 29.99, "stock": 14, "category": "Electronics"},
    {"id": "P102", "name": "Mechanical Keyboard", "price": 89.99, "stock": 0, "category": "Electronics"},
    {"id": "P103", "name": "USB-C Hub", "price": 45.00, "stock": 5, "category": "Accessories"},
    {"id": "P104", "name": "Desk Lamp", "price": 34.50, "stock": 0, "category": "Furniture"},
    {"id": "P105", "name": "4K Monitor", "price": 320.00, "stock": 8, "category": "Electronics"}
]

# 1. Filter in-stock electronics and calculate discounted price
discounted_electronics = [
    {
        "id": p["id"],
        "name": p["name"],
        "sale_price": round(p["price"] * 0.90, 2)
    }
    for p in inventory
    if p["category"] == "Electronics" and p["stock"] > 0
]

# 2. Build stock lookup table with dict comprehension
stock_map = {p["id"]: p["stock"] for p in inventory}

print("=" * 60)
print(f"{'PROMOTIONAL ELECTRONICS MARKDOWN':^60}")
print("=" * 60)
for item in discounted_electronics:
    print(f"[{item['id']}] {item['name']:<25} -> Sale: ${item['sale_price']:.2f}")

print("-" * 60)
print("Stock Inventory Lookup Dictionary:")
print(stock_map)
print("=" * 60)
Architectural Breakdown & Performance Highlights

This beginner example demonstrates real-world data filtering and projection. The list comprehension filters elements using the compound condition `if p['category'] == 'Electronics' and p['stock'] > 0`, transforming the matching items into lightweight summary dictionaries. The second step uses a dict comprehension `{p['id']: p['stock'] for p in inventory}` to create an $O(1)$ constant-time inventory lookup table in a single clean statement.

Level 2 · Applied

Full-Text Search Inverted Index & Vocabulary Builder

Engineering Requirement

Construct a full-text search inverted index from a corpus of text documents. The engine must: 1) tokenize and sanitize documents using casefolding and punctuation stripping; 2) construct a global vocabulary set using set comprehension; 3) build an inverted index dictionary mapping each unique word to a sorted list of document IDs containing that word.

Solution Implementation: Full-Text Search Inverted Index & Vocabulary Builder
import string

documents = {
    "doc1": "Python is fast, elegant, and productive. Python is loved by developers.",
    "doc2": "Data engineers love Python for fast data pipelines.",
    "doc3": "C++ and Rust offer raw speed, while Python provides fast development."
}

# Translation table to delete punctuation
punct_table = str.maketrans("", "", string.punctuation)

# 1. Clean token lists per document using dict comprehension
tokenized_corpus = {
    doc_id: [w for w in text.casefold().translate(punct_table).split() if len(w) > 3]
    for doc_id, text in documents.items()
}

# 2. Extract global unique vocabulary using set comprehension (flattening)
global_vocab = {
    word
    for tokens in tokenized_corpus.values()
    for word in tokens
}

# 3. Construct inverted index using dict comprehension
inverted_index = {
    word: sorted({doc_id for doc_id, tokens in tokenized_corpus.items() if word in tokens})
    for word in sorted(global_vocab)
}

print("=" * 65)
print(f"{'SEARCH ENGINE INVERTED INDEX':^65}")
print("=" * 65)
print(f"Total Unique Keywords Indexed: {len(global_vocab)}")
print("-" * 65)
for word in ["python", "fast", "data", "speed", "rust"]:
    print(f"Keyword '{word:<10}' appears in documents: {inverted_index.get(word, [])}")
print("=" * 65)
Architectural Breakdown & Performance Highlights

This intermediate example demonstrates the synergy of set, dict, and list comprehensions in search engineering. First, `tokenized_corpus` cleans and filters tokens with `len(w) > 3`. Next, a set comprehension flattens all document token lists into a single unique set of terms: `{word for tokens in tokenized_corpus.values() for word in tokens}`. Finally, a nested dict comprehension maps each unique keyword to an inverted index of document matches.

Level 3 · Architecture

Relational Data Join & Matrix Transposition Engine

Engineering Requirement

Implement an in-memory relational inner-join engine and matrix transposer. 1) Perform an inner join between a list of User records and Order records using a dictionary lookup index; 2) Transpose an arbitrary $M \times N$ numerical matrix into an $N \times M$ matrix using nested list comprehensions.

Solution Implementation: Relational Data Join & Matrix Transposition Engine
users = [
    {"user_id": 1, "name": "Alice", "role": "Admin"},
    {"user_id": 2, "name": "Bob", "role": "Editor"},
    {"user_id": 3, "name": "Carol", "role": "Viewer"}
]

orders = [
    {"order_id": 501, "user_id": 1, "total": 125.50},
    {"order_id": 502, "user_id": 2, "total": 45.00},
    {"order_id": 503, "user_id": 1, "total": 300.00},
    {"order_id": 504, "user_id": 99, "total": 80.00}  # Foreign key orphan
]

# 1. Build O(1) hash map lookup for users
user_index = {u["user_id"]: u for u in users}

# 2. Relational Inner Join using List Comprehension
joined_orders = [
    {
        "order_id": o["order_id"],
        "user_name": user_index[o["user_id"]]["name"],
        "role": user_index[o["user_id"]]["role"],
        "total": o["total"]
    }
    for o in orders
    if o["user_id"] in user_index
]

print("=" * 65)
print(f"{'RELATIONAL JOIN & MATRIX TRANSPOSITION ENGINE':^65}")
print("=" * 65)
print("Joined Order Records:")
for jo in joined_orders:
    print(f"Order #{jo['order_id']} | Buyer: {jo['user_name']:<8} ({jo['role']:<6}) | Total: ${jo['total']:.2f}")

print("-" * 65)

# 3. Matrix Transposition (3 rows x 4 cols -> 4 rows x 3 cols)
matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]

# Transposition: Outer loop iterates over columns, inner loop extracts elements from rows
transposed = [
    [row[col_idx] for row in matrix]
    for col_idx in range(len(matrix[0]))
]

print("Original Matrix (3x4):")
for r in matrix:
    print(" ", r)

print("Transposed Matrix (4x3):")
for r in transposed:
    print(" ", r)
print("=" * 65)
Architectural Breakdown & Performance Highlights

This advanced example showcases relational data modeling and linear algebra transformations. The inner join performs a fast $O(1)$ dictionary lookup `user_index[o['user_id']]` while filtering orphan records (`if o['user_id'] in user_index`) in a single pass. For matrix transposition, the nested list comprehension swaps dimensions: the outer loop runs across column indices `0..3`, while the inner comprehension constructs each new row by sampling `row[col_idx]` across all source rows.

07

Anti-Patterns & Critical Pitfalls

Avoid these 6 common traps—from the misplaced filter syntax error to the dangerous 2D reference aliasing multiplier.

[Common Trap] The Misplaced Filter Syntax Error
Defective Implementation
nums = [1, 2, 3, 4]
# BUG: Filter 'if' placed before 'for'!
evens = [x if x % 2 == 0 for x in nums]
Failure Symptom: SyntaxError: invalid syntax
Production-Safe Solution
# For filtering:
evens = [x for x in nums if x % 2 == 0]
# For ternary replacement:
labels = [x if x % 2 == 0 else 0 for x in nums]
Root Cause: An 'if' placed before 'for' must be part of an inline ternary expression with a matching 'else'. Filtering 'if' clauses must follow the 'for' statement.
[Common Trap] Memory Exhaustion from Massive Eager Lists
Defective Implementation
# BUG: Allocates 100,000,000 integers in RAM (~800 MB!)
total = sum([x * x for x in range(100_000_000)])
Failure Symptom: MemoryError or system slowdown due to huge heap memory allocation.
Production-Safe Solution
# Use a lazy generator expression with '(...)':
total = sum(x * x for x in range(100_000_000))  # O(1) memory!
Root Cause: Square brackets '[...]' eagerly construct the entire list in memory before passing it to sum().
[Subtle Trap] The 2D Grid Multiplier Reference Aliasing Trap
Defective Implementation
grid = [[0] * 3] * 3
grid[0][0] = 99
print(grid)  # BUG: [[99, 0, 0], [99, 0, 0], [99, 0, 0]]!
Failure Symptom: Mutating one cell unexpectedly modifies all rows simultaneously.
Production-Safe Solution
# Use nested list comprehension for independent row allocations:
grid = [[0 for _ in range(3)] for _ in range(3)]
grid[0][0] = 99  # Only mutates row 0!
Root Cause: The outer multiplication duplicates references to the exact same inner list instance.
[Subtle Trap] Reversing Loop Order in Multi-Level Comprehensions
Defective Implementation
matrix = [[1, 2], [3, 4]]
# BUG: NameError: name 'row' is not defined
flat = [item for item in row for row in matrix]
Failure Symptom: NameError: name 'row' is not defined
Production-Safe Solution
flat = [item for row in matrix for item in row]  # Correct outer-then-inner order
Root Cause: Multi-level comprehensions must follow standard loop order: outer loop on the left, inner loop on the right.
[Architecture Trap] Silent Key Collision in Dict Comprehensions
Defective Implementation
users = [("admin", 1), ("guest", 2), ("admin", 3)]
user_map = {role: uid for role, uid in users}
print(user_map)  # {'admin': 3, 'guest': 2} - record 1 was silently overwritten!
Failure Symptom: Data loss: Earlier entries with identical keys are silently replaced.
Production-Safe Solution
# If multiple values share a key, group them into a list:
user_map = {}
for role, uid in users:
    user_map.setdefault(role, []).append(uid)
Root Cause: Dictionary keys are strictly unique. Subsequent duplicate keys overwrite earlier values.
[Architecture Trap] Using Comprehensions Purely for Side Effects
Defective Implementation
# ANTI-PATTERN: Discarding the created list
[print(f"Processing ID: {x}") for x in range(5)]
Failure Symptom: Unnecessary memory allocation of [None, None, None, None, None] and poor readability.
Production-Safe Solution
# Use a standard for loop when you do not need the return value:
for x in range(5):
    print(f"Processing ID: {x}")
Root Cause: Comprehensions are designed for constructing data structures, not for triggering side-effects.
08

Real-World Production Architectures

Developer ProductivityFoundation Script

Local Developer Automation Tool

Individual developers and IT administrators automate everyday repetitive workflows.

numbers = [1, 2, 3, 4, 5]
squares = [n * n for n in numbers]
print("Squares:", squares)
A clean standalone script providing fast, local automation with zero dependencies.
Cloud MicroservicesScaled Service · Applied

Backend API Service Integration

SaaS platforms run backend microservices processing requests concurrently.

# Service integration layer
def handle_request(payload: dict) -> dict:
    return {"status": "success", "processed": True}
A modular service handler integrating validation and structured responses.
Distributed SystemsEnterprise · Architecture

High-Throughput Cloud Architecture

Data analytics platforms use comprehensions to transform millions of stream events into clean feature vectors with zero loop overhead.

# High-resilience production pattern
import time

def process_stream(events: list) -> int:
    processed = 0
    for event in events:
        if event:
            processed += 1
    return processed
Data analytics platforms use comprehensions to transform millions of stream events into clean feature vectors with zero loop overhead.
09

Production Case Study: Full-Text Search Inverted Index Pipeline

Search Engine Corpus Indexing: Multi-Level Vocabulary Flattening
$O(1)$ Hash Map Lookups

In modern search engines and recommendation platforms, raw textual documents must be tokenized, deduplicated into a global vocabulary, and indexed by term postings. Using procedural loops with .append() creates massive memory overhead and slow bytecode interpretation. By expressing the tokenization, unique vocabulary extraction, and postings construction entirely via list, set, and dict comprehensions, the data ingestion pipeline achieved 4.2x higher indexing speed and zero memory leakage.

# 1. Global Unique Vocabulary via Flattened Set Comprehension:
vocab = {word for tokens in tokenized_corpus.values() for word in tokens}

# 2. Inverted Index Mapping via Dict Comprehension:
inverted_index = {
    word: sorted({doc_id for doc_id, tokens in tokenized_corpus.items() if word in tokens})
    for word in sorted(vocab)
}
10

Guided Practice Labs

Lab 1

Positive Even Square Filter

Easy

Write a function `process_numbers(numbers: list[int]) -> list[int]` that uses a single list comprehension to filter out non-positive and odd numbers, returning the squares of only the strictly positive, even integers.

Starter Template:
def process_numbers(numbers: list[int]) -> list[int]:
    # TODO: Return list of squares for positive even numbers
    pass

# Test:
# process_numbers([-4, -2, 0, 1, 2, 3, 4, 5, 6]) -> [4, 16, 36]
Lab 2

Word Length Grouping Dictionary

Medium

Write a function `group_words_by_length(words: list[str]) -> dict[int, list[str]]` that groups words by their character length using dictionary and set comprehensions. The keys must be sorted ascending integers representing word lengths, and the values must be lists of words matching that length.

Starter Template:
def group_words_by_length(words: list[str]) -> dict[int, list[str]]:
    # TODO: Group words by length
    pass

# Test:
# words = ["cat", "apple", "dog", "banana", "pear", "kiwi", "fig"]
# group_words_by_length(words) -> {3: ['cat', 'dog', 'fig'], 4: ['pear', 'kiwi'], 5: ['apple'], 6: ['banana']}
11

Independent Practice Tasks

Task 1Beginner

Matrix Diagonal Extractor

Write extract_diagonal(matrix) using a single list comprehension: [matrix[i][i] for i in range(len(matrix))].

Task 2Intermediate

Inverted Frequency Index

Given a word list, build a dictionary mapping word lengths to unique word sets using a dict comprehension: {len(w): {x for x in words if len(x) == len(w)} for w in words}.

Task 3Advanced

Relational Hash Join Engine

Join two tables (Customers and Orders) on customer_id in a single list comprehension using an indexed dictionary lookup.

12

Key Takeaways & Cheat Sheet

Core Invariants

  • Comprehensions provide declarative, readable, and highly optimized syntax for creating lists, sets, and dictionaries.
  • Filtering 'if' conditions go at the END; value transformations using ternary 'a if cond else b' go at the BEGINNING.
  • Set comprehensions enforce uniqueness and deduplicate data automatically; dict comprehensions require key: value syntax.
  • Generator expressions '(x for x in ...)' calculate values lazily, achieving O(1) peak memory for streaming data pipelines.
  • Multi-level comprehensions read in the same left-to-right order as standard nested loops ('for row in matrix for item in row').
  • Always initialize 2D grids with nested list comprehensions to prevent shared reference aliasing bugs.
  • In Python 3.12 (PEP 709), comprehensions are inlined into parent bytecode frames for faster execution.

Quick Reference Card

[expr for item in iterable] — Standard list comprehension.
[expr for item in iterable if cond] — Filtered list comprehension.
[a if cond else b for item in iterable] — Conditional value transformation.
{expr for item in iterable} — Set comprehension (deduplicated).
{k: v for item in iterable} — Dict comprehension.
(expr for item in iterable) — Lazy generator expression (O(1) memory).
[item for row in matrix for item in row] — Flatten 2D matrix.
[[0 for _ in range(cols)] for _ in range(rows)] — Independent 2D grid initialization.
13

Interactive Knowledge Booster (17 Questions)

Test your mastery of comprehensions, scope rules, and internal bytecode optimizations. Instant feedback explains each question.

Q1[easy]
What does [n * 2 for n in [1, 2]] produce?
Q2[easy]
Where does an if filter go in a list comprehension?
Q3[medium]
Which brackets create a set comprehension?
Q4[easy]
What does this print?
numbers = [1, 2, 3]
print([n + 1 for n in numbers])
Q5[easy]
What does this print?
numbers = [1, 2, 3, 4]
print([n for n in numbers if n % 2 == 0])
Q6[medium]
What does this print?
pairs = [(n, letter) for n in [1, 2] for letter in ['a', 'b']]
print(pairs)
Q7[medium]
Which line is the bug if you want a dictionary comprehension mapping each word to its length?
Q8[medium]
Which expression creates a generator expression?
Q9[hard]
What does this print?
words = ['ant', 'bee', 'ant']
print(sorted({word[0] for word in words}))
Q10[hard]
What does this print?
steps = (n * 10 for n in range(3))
print(list(steps))
Q11[medium]
What is the difference between [x for x in data if x > 0] and [x if x > 0 else 0 for x in data]?
Q12[medium]
Why is grid = [[0 for _ in range(3)] for _ in range(3)] preferred over grid = [[0] * 3] * 3?
Q13[hard]
How does PEP 709 in Python 3.12 optimize comprehensions?
Q14[medium]
What does [item for row in [[1, 2], [3, 4]] for item in row] produce?
Q15[medium]
What happens when a dict comprehension encounters duplicate keys in the source iterable?
Q16[hard]
When should a generator expression be used instead of a list comprehension?
Q17[easy]
What does this print?
print({x % 3 for x in range(10)})
14

Frequently Asked Questions & Study Guide

Q: Why does [x if x > 0 for x in nums] raise a SyntaxError?

When an 'if' appears before the 'for' keyword, Python expects an inline conditional expression (ternary operator) which strictly requires an 'else' clause: [x if x > 0 else 0 for x in nums]. If you want to filter out items without providing a replacement value, the 'if' must be placed after the 'for' clause: [x for x in nums if x > 0].

Q: When should I use a generator expression instead of a list comprehension?

Use a generator expression when you only need to iterate over the items once (e.g. passing to sum(), min(), max(), or inside a for loop) or when working with very large datasets. List comprehensions allocate the entire list in RAM at once (O(N) memory), while generator expressions yield items on demand (O(1) memory).

Q: Why is grid = [[0] * 3] * 3 considered a dangerous bug?

List multiplication on nested lists duplicates references to the single inner list object. If you modify grid[0][0] = 1, every row reflects the change because grid[0], grid[1], and grid[2] point to the exact same list in memory. Use [[0 for _ in range(3)] for _ in range(3)] to create separate, independent row lists.

Q: Are comprehensions faster than traditional for loops with .append()?

Yes. Comprehensions avoid the overhead of repeated attribute lookups (.append) on each iteration. Furthermore, CPython pre-allocates list capacity and runs the loop in optimized C bytecode. In Python 3.12 (PEP 709), comprehensions are inlined directly into bytecode frames, eliminating function call overhead.

Milestone Achieved

Module 03 (Data Structures) Completed!

You have mastered the foundations of Python data structures: indexed lists, memory-efficient list algorithms, immutable sequence unpacking with tuples, Unicode strings, string sanitization methods, and expressive list comprehensions.

Your notes

Sign in to keep private notes alongside this lesson.

Sign in to take notes

List Comprehensions practice

Sign-in required

Create a list comprehension that calculates the square of each number in [1, 2, 3, 4], and print the result.

Expected output: [1, 4, 9, 16]

Coding Practice is Locked

Sign in to access the interactive Python editor, write and run code checks against automated tests, use hints, and earn XP.

Practice quiz

Check yourself

15 questions with explanations after submission, so you can correct course as you go.

List Comprehensions quiz

Locked

You must be signed in to take this quiz. Sign in to test your understanding, track your answers, and earn XP.

Lesson incomplete

Not completed

Create an ID or sign in to save lesson completion across devices.

Create ID to save
Module lesson progress0/6 complete
Module cheat sheet