Lompati ke konten utama
eLearner.app
Modul 6 · Pelajaran 3 dari 423/36 dalam kursus~10 min
Pelajaran modul (3/4)

Ekspresi pembangkit

A generator expression is like a list comprehension, but with parentheses instead of square brackets. The difference is dramatic: it doesn't build a list in memory, it produces elements on-demand, one at a time.

Python
gen = (n * n for n in range(1_000_000))
# istantaneo, memoria costante: nessun calcolo ancora fatto

list_comp = [n * n for n in range(1_000_000)]
# alloca 1M di int in memoria

Laziness (lazy evaluation)

The generator does nothing until someone asks for the next value:

Python
gen = (n * n for n in range(5))
next(gen)    # 0    (calcolato adesso)
next(gen)    # 1
next(gen)    # 4
# ... e così via, fino a StopIteration

It gets exhausted: after consuming all elements, it is empty forever. To reuse it, you must recreate it.

When to use it

When you pass the results to a function that consumes them in sequence:

Python
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costante

sum, any, all, max, min, "".join(...) all accept generators. If the outer function only requires the call parentheses, you can omit the generator's own:

Python
sum((n * n for n in range(10)))    # OK
sum(n * n for n in range(10))      # IDENTICO, più leggibile

any and all: short-circuit

any(...) and all(...) stop iterating as soon as they have the answer. With a generator, the following elements aren't even computed.

Python
nums = [1, 2, 3, 4, 5]
any(n > 3 for n in nums)    # True (si ferma a 4)
all(n > 0 for n in nums)    # True
all(n > 2 for n in nums)    # False (si ferma a 1)

Pattern: lazy pipeline

Python
righe = (linea.strip() for linea in testo.splitlines())
non_vuote = (r for r in righe if r)
prime_dieci = []
for r in non_vuote:
    prime_dieci.append(r)
    if len(prime_dieci) == 10:
        break

No intermediate list, even on huge inputs.

Consuming generators with sum, any, all

Generator expressions are perfect for passing directly to functions that consume iterables, like sum(), any(), or all(). In this case, you can omit the outer parentheses of the generator expression, simply writing:

Python
squares_sum = sum(x**2 for x in range(10))

This keeps your code clean and highly memory-efficient.

Try it

Latihan#python.m6.l3.e1
Upaya: 0Memuat…

Compute the sum of the squares of the numbers from 1 to 100 (inclusive) using a generator expression inside sum(). Assign it to `tot`. Evaluate `tot`.

Memuat editor…
Tunjukkan petunjuk

range(1, 101) includes 100.

Solusi tersedia setelah 3 upaya

Review exercise

Latihan#python.m6.l3.e2
Upaya: 0Memuat…

Given `words = ['ciao', 'mondo', 'PYTHON', 'java']`, use any() with a generator expression to check whether AT LEAST one word is uppercase (.isupper()). Assign the result to `has_uppercase`. Evaluate `has_uppercase`.

Memuat editor…
Tunjukkan petunjuk

any(p.isupper() for p in words)

Solusi tersedia setelah 3 upaya

Additional challenge

Latihan#python.m6.l3.e3
Upaya: 0Memuat…

Use a generator expression passed directly to the `sum()` function to calculate the sum of the squares of all integers from 1 to 100 inclusive. Store the result in `total_sum` and evaluate it.

Memuat editor…
Tunjukkan petunjuk

Write total_sum = sum(x**2 for x in range(1, 101)). Double parentheses are not needed.

Solusi tersedia setelah 3 upaya