Lesson explanation
After this lesson, you will be able to:
sum(), any(), or all() without creating an intermediate list.A list comprehension creates a list of results immediately:
adjusted = [score + 5 for score in scores]A generator expression uses parentheses instead of brackets. It describes values to be produced when an iterator requests them, rather than creating the result list right away:
adjusted = (score + 5 for score in scores)Use this when an operation can process values one by one—for example sum(), any(), or all(). You can pass the expression directly into a function. For a single generator argument, the outer generator parentheses can often be omitted: sum(x * 2 for x in values).
Unlike a list, a generator is single-pass. After you consume it, iterating over the same generator again yields no values. If you need the values multiple times, use a list comprehension, materialize the generator with list(), or create a new generator for each pass.
any() and all() may stop early: any() stops at the first truthy item, and all() stops at the first falsy item. The rules for empty inputs remain the same as the previous lesson (any is false; all is true). Generator expressions are especially natural for one-pass checks.
base_prices = [12, 20, 8]
total = sum(price * 2 for price in base_prices)
print(f"Total: {total}")Output:
Total: 80The multiplication is evaluated as sum() requests each item; no separate doubled-price list is needed.
readings = [18, -1, 24, 0]
valid_total = sum(value for value in readings if value >= 0)
print(valid_total)Output:
42The if keeps invalid negative readings out of the calculation while preserving a valid zero.
labels = ["ready", "paused", "ready"]
has_pause = any(label == "paused" for label in labels)
print(f"Paused: {has_pause}")Output:
Paused: Trueany() can finish as soon as the generator supplies one match.
values = (part.upper() for part in ["a", "b"])
print(list(values))
print(list(values))Output:
['A', 'B']
[]The second pass is empty because values was consumed. Use a list if both passes must contain results.
| Need | Preferred approach |
|---|---|
| Keep results for reuse | [expression for item in items] |
| Process results once | (expression for item in items) |
| Aggregate values | sum(expression for item in items) |
| Check at least one match | any(predicate for item in items) |
| Check every value | all(predicate for item in items) |
| Reuse results later | Materialize with list(...), or recreate the generator |
all() on an empty generator as proof that a batch contained checks.sum(), any(), or all() when a generator is clearer.