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

Ekspresi pembangkit

ekspresi generator seperti pemahaman daftar, tetapi dengan tanda kurung, bukan tanda kurung siku. Perbedaannya sangat dramatis: itu tidak membuat daftar di memori, itu menghasilkan elemen sesuai permintaan, satu per satu.

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

Kemalasan (evaluasi malas)

Generator tidak melakukan apa pun sampai seseorang meminta nilai berikutnya:

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

Ia menjadi habis: setelah mengkonsumsi semua elemen, ia kosong selamanya. Untuk menggunakannya kembali, Anda harus membuatnya kembali.

Kapan menggunakannya

Saat Anda meneruskan hasilnya ke fungsi yang menggunakannya secara berurutan:

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

sum, any, all, max, min, "".join(...) semuanya menerima generator. Jika fungsi luar hanya memerlukan tanda kurung panggilan, Anda bisa hilangkan milik generatornya:

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

any dan all: hubungan arus pendek

any(...) dan all(...) berhenti mengulangi segera setelah mereka mendapatkan jawabannya. Dengan generator, elemen berikut bahkan tidak dihitung.

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)

Pola: pipa malas

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

Tidak ada daftar perantara, bahkan pada masukan yang besar.

Mengkonsumsi generator dengan jumlah, apa saja, semua

Ekspresi generator sempurna untuk diteruskan langsung ke fungsi yang menggunakan iterable, seperti sum(), any(), atau all(). Dalam hal ini, Anda dapat menghilangkan tanda kurung luar dari ekspresi generator, cukup dengan menulis:

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

Ini menjaga kode Anda tetap bersih dan sangat hemat memori.

Cobalah

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

Hitung jumlah kuadrat angka dari 1 hingga 100 (inklusif) menggunakan ekspresi generator di dalam sum(). Tetapkan ke `tot`. Evaluasi `tot`.

Memuat editor…
Tunjukkan petunjuk

rentang(1, 101) mencakup 100.

Solusi tersedia setelah 3 upaya

Tinjau latihan

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

Mengingat `words = ['ciao', 'mondo', 'PYTHON', 'java']`, gunakan any() dengan ekspresi generator untuk memeriksa apakah SETIDAKNYA satu kata adalah huruf besar (.isupper()). Tetapkan hasilnya ke `has_uppercase`. Evaluasi `has_uppercase`.

Memuat editor…
Tunjukkan petunjuk

any(p.isupper() untuk p dalam kata-kata)

Solusi tersedia setelah 3 upaya

Tantangan tambahan

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

Tulis total_sum = sum(x**2 untuk x dalam rentang(1, 101)). Tanda kurung ganda tidak diperlukan.

Solusi tersedia setelah 3 upaya