שיעורי מודול (3/4)
ביטוי מחולל
ביטוי מחולל הוא כמו הבנת רשימה, אבל עם סוגריים במקום סוגריים מרובעים. ההבדל הוא דרמטי: הוא לא בונה רשימה בזיכרון, הוא מייצר אלמנטים על פי דרישה, אחד בכל פעם.
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עצלות (הערכה עצלנית)
המחולל לא עושה כלום עד שמישהו מבקש את הערך הבא:
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הוא מותש: לאחר צריכת כל האלמנטים, הוא ריק לנצח. כדי לעשות בו שימוש חוזר, עליך ליצור אותו מחדש.
מתי להשתמש בו
כאשר אתה מעביר את התוצאות לפונקציה שצורכת אותן ברצף:
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costantesum, any, all, max, min, "".join(...) כולם מקבלים גנרטורים.
אם הפונקציה החיצונית דורשת רק את סוגרי השיחה, אתה יכול
השמט את זה של הגנרטור:
sum((n * n for n in range(10))) # OK
sum(n * n for n in range(10)) # IDENTICO, più leggibileany וall: קצר חשמלי
any(...) ו-all(...) מפסיקים לבצע איטרציה ברגע שיש להם את התשובה.
עם גנרטור, האלמנטים הבאים אפילו לא מחושבים.
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)דפוס: צינור עצלן
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אין רשימת ביניים, אפילו בתשומות ענקיות.
צריכת גנרטורים עם סכום, כל, הכל
ביטויי מחולל מושלמים למעבר ישירות לפונקציות שצורכות איטרנס, כמו sum(), any() או all(). במקרה זה, אתה יכול להשמיט את הסוגריים החיצוניים של ביטוי המחולל, פשוט לכתוב:
squares_sum = sum(x**2 for x in range(10))זה שומר על הקוד שלך נקי וחסכוני מאוד בזיכרון.
נסה את זה
חשב את סכום הריבועים של המספרים מ-1 עד 100 (כולל) באמצעות ביטוי מחולל בתוך sum(). הקצה אותו ל'טוט'. הערך `טוט`.
הצג רמז
range(1, 101) כולל 100.
הפתרון זמין לאחר 3 ניסיונות
סקירת התרגיל
בהינתן `words = ['ciao', 'mondo', 'PYTHON', 'java']`, השתמש ב- any() עם ביטוי מחולל כדי לבדוק אם לפחות מילה אחת היא אותיות גדולות (.isupper()). הקצה את התוצאה ל'יש_אותיות גדולות'. הערך את 'יש_אותיות גדולות'.
הצג רמז
any(p.isupper() עבור p במילים)
הפתרון זמין לאחר 3 ניסיונות
אתגר נוסף
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.
הצג רמז
כתוב total_sum = sum(x**2 עבור x בטווח(1, 101)). אין צורך בסוגריים כפולים.
הפתרון זמין לאחר 3 ניסיונות