Modül dersleri (3/4)
Jeneratör ifadesi
üretici ifadesi bir liste kavrama gibidir, ancak köşeli parantezler yerine köşeli parantezler**. Fark dramatik: bellekte bir liste oluşturmaz, **talep üzerine** öğeler üretir, birer birer.
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 memoriaTembellik (tembel değerlendirme)
Birisi bir sonraki değeri isteyene kadar jeneratör hiçbir şey yapmaz:
gen = (n * n for n in range(5))
next(gen) # 0 (calcolato adesso)
next(gen) # 1
next(gen) # 4
# ... e così via, fino a StopIterationTükenir: Tüm elementleri tükettikten sonra sonsuza kadar boştur. Yeniden kullanmak için yeniden oluşturmanız gerekir.
Ne zaman kullanılmalı?
Sonuçları sırayla tüketen bir işleve aktardığınızda:
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costantesum, any, all, max, min, "".join(...) hepsi jeneratörleri kabul eder.
Dış işlev yalnızca çağrı parantezlerini gerektiriyorsa, şunları yapabilirsiniz:
jeneratörün kendisini hariç tutun:
sum((n * n for n in range(10))) # OK
sum(n * n for n in range(10)) # IDENTICO, più leggibileany ve all: kısa devre
any(...) ve all(...) yanıtı alır almaz yinelemeyi bırakırlar.
Bir jeneratörde aşağıdaki öğeler hesaplanmaz bile.
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)Desen: tembel boru hattı
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Çok büyük girdilerde bile ara liste yok.
Jeneratörleri toplam, herhangi biri, tümü ile tüketme
Oluşturucu ifadeleri, sum(), any() veya all() gibi yinelenebilirleri tüketen işlevlere doğrudan geçmek için mükemmeldir. Bu durumda, oluşturucu ifadesinin dış parantezlerini çıkararak şunu yazabilirsiniz:
squares_sum = sum(x**2 for x in range(10))Bu, kodunuzu temiz tutar ve bellek açısından yüksek verimlilik sağlar.
Deneyin
sum() içindeki bir oluşturucu ifadesini kullanarak 1'den 100'e kadar (dahil) sayıların karelerinin toplamını hesaplayın. Bunu "toplam"a atayın. 'Toplam'ı değerlendirin.
İpucu göster
range(1, 101) 100'ü içerir.
3 denemeden sonra çözüm mevcut
Alıştırmayı gözden geçirin
`words = ['ciao', 'mondo', 'PYTHON', 'java']` verildiğinde, EN AZ bir kelimenin büyük harf (.isupper()) olup olmadığını kontrol etmek için bir jeneratör ifadesiyle any() kullanın. Sonucu "has_uppercase"e atayın. 'has_uppercase' değerini değerlendirin.
İpucu göster
herhangi(p.isupper() kelimelerdeki p için)
3 denemeden sonra çözüm mevcut
Ek zorluk
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.
İpucu göster
Toplam_toplam = toplam(x**2, aralıktaki(1, 101) için) yazın. Çift parantezlere gerek yoktur.
3 denemeden sonra çözüm mevcut