Comprehensions & Generator Expressions
One syntax for all collection transformations
Section titled “One syntax for all collection transformations”TypeScript developers reach for .map(), .filter(), and .reduce() chained on arrays. This works, but it requires creating intermediate arrays at each step and cannot natively produce a Set or an object directly. Python has comprehension syntax built into the language for four forms: list, dict, set, and generator. The mental model is: [expression for item in iterable if condition].
List comprehension vs map/filter
Section titled “List comprehension vs map/filter”The most common case is transforming a collection while optionally filtering it. In TypeScript this is two separate method calls. In Python it is a single expression.
// TypeScript: chained .map() and .filter()const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// squares of even numbersconst result = numbers .filter(n => n % 2 === 0) .map(n => n ** 2);
console.log(result); // [4, 16, 36, 64, 100]
// Building an object from an array requires reduce or Object.fromEntriesconst words = ["hello", "world", "typescript"];const wordLengths = Object.fromEntries( words.map(w => [w, w.length]));console.log(wordLengths); // { hello: 5, world: 5, typescript: 10 }# Python: comprehensions for list, dict, set, and generator
numbers = list(range(1, 11))
# squares of even numbers — single expressionresult = [n ** 2 for n in numbers if n % 2 == 0]print(result) # [4, 16, 36, 64, 100]
# Dict comprehension — no need for Object.fromEntrieswords = ["hello", "world", "python"]word_lengths = {word: len(word) for word in words}print(word_lengths) # {'hello': 5, 'world': 5, 'python': 6}
# Set comprehension — duplicates are automatically removedunique_lengths = {len(word) for word in words}print(unique_lengths) # {5, 6}All four forms
Section titled “All four forms”List comprehension — produces an eager list:
squares = [x ** 2 for x in range(1, 6)]# [1, 4, 9, 16, 25]Dict comprehension — produces a dict:
word_lengths = {word: len(word) for word in ["hello", "world", "python"]}# {'hello': 5, 'world': 5, 'python': 6}Set comprehension — produces a set (no duplicate values):
unique_lengths = {len(word) for word in ["hi", "hello", "hey", "world"]}# {2, 3, 5}Generator expression — produces a lazy generator (parentheses, not brackets):
gen = (x ** 2 for x in range(5))# Nothing is computed yet. Values are produced only when iterated.print(list(gen)) # [0, 1, 4, 9, 16]The syntax is identical across all four forms; only the outer delimiter changes: [] for list, {} with a colon for dict, {} without a colon for set, and () for generator.
Try it
Section titled “Try it”# List comprehensionsquares = [x ** 2 for x in range(1, 6)]print(squares)
# With filter conditionevens = [x for x in range(10) if x % 2 == 0]print(evens)
# Dict comprehensionword_lengths = {word: len(word) for word in ["hello", "world", "python"]}print(word_lengths)
# Set comprehension -- unique values onlyunique_lengths = {len(word) for word in ["hi", "hello", "hey", "world"]}print(sorted(unique_lengths))
# Generator expression -- lazygen = (x ** 2 for x in range(5))print(list(gen))Loading Python runtime (first run only)…