Skip to content
Generator Expressions
step 1/4

Reading — step 1 of 4

Learn

~3 min readGenerators and Iterators

Generator Expressions

You already know list comprehensions. A generator expression looks almost identical — swap the square brackets for parentheses — but that one-character change flips the execution model. A list comprehension is eager: it computes every value right now and stores them all in memory. A generator expression is lazy: it builds a tiny generator object (the same kind you met with yield in the last lesson) that computes each value only when something asks for it.

python

The list costs memory proportional to its length. The generator expression costs a constant couple hundred bytes whether the range is one thousand or one billion — because it stores the recipe, not the results.

The idiom: feed aggregators directly

The killer use case is piping values straight into a function that consumes an iterable — sum, max, min, any, all, sorted, str.join:

python

Note there is no doubled parenthesis: when the generator expression is the sole argument, the call's own parentheses are enough. With a second argument you must wrap it yourself — sum((x for x in data), 0) — because sum(x for x in data, 0) is a straight SyntaxError ("Generator expression must be parenthesized").

any and all fed by a generator expression also short-circuit: the moment any sees a truthy value it stops pulling, and the remaining values are never computed at all. A list comprehension would have computed every one of them first.

The traps

One-shot consumption. Like every generator, a generator expression is exhausted after one pass:

python

That silent 0 is the nasty part — no exception tells you the generator was spent. If you need two passes, rebuild the expression or use a list.

Late name lookup. Only the outermost iterable is evaluated immediately; the body runs when the generator is consumed — including reads of outside variables:

python

No len, no indexing. len(g) and g[0] raise TypeError. If you need the count, random access, or repeated iteration, that is precisely when a list comprehension is the right tool. Lazy is not automatically better — it wins when you consume once and the data is large.

Your exercise

Read an integer N, then print the sum of squares from 1 to N inclusive, computed with a generator expression inside sum(...). The mistake the grader will catch is the off-by-one: range(1, n) stops at n - 1, so for input 5 you would print 30 while the grader expects exactly 55. Use range(1, n + 1), and print only the number — stdout is compared character-for-character.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…