קורס פייתון למתחילים אונליין חינם - דווין קורס תכנותקורס פייתון למתחילים אונליין חינם - דווין קורס תכנות

פייתון גנרטורים

על מה נעבור

פייתון גנרטורים - מבוא

גנרטורים בפייתון הם סוג מיוחד של פונקציות, המאפשרות לנו ליצור איטרטורים (Iterators) על חישובים. הם מספקים דרך יעילה וחסכונית לטפל במצבים שבהם יש צורך לטפל ברצפים של ערכים גדולים או אינסופיים.

התכונה המרכזית של גנרטורים היא היכולת להפסיק ולהמשיך את הריצה באמצעות המילה השמורה yield. כאשר הפונקציה מגיעה ל-yield, היא "זוכרת" את המצב הנוכחי שלה ומחזירה את הערך שאחרי ה-yield. בפעם הבאה שהגנרטור יקרא, הריצה תמשיך מנקודה זו.

כדי להמחיש את התכונות הבסיסיות של גנרטורים, בואו נתחיל עם דוגמה פשוטה:

1def count_up_to(max_val):
2 n = 0
3 while n < max_val:
4 yield n
5 n += 1
6
7counter = count_up_to(3)
8print(next(counter)) # 0
9print(next(counter)) # 1
10print(next(counter)) # 2
11print(next(counter)) # StopIteration

בדוגמה זו, count_up_to היא גנרטור שמחזיר ערכים עוקבים מ-0 עד הערך המקסימלי שהוגדר. בכל פעם שאנו קוראים ל-next(counter), הגנרטור ממשיך את הריצה שלו מהנקודה האחרונה שבה הופסקה.

הגדירו גנרטור בשם my_range שמקבל שני ערכים start ו-end, והוא מחזיר את הערכים מ-start עד end-1 (כולל start אך לא כולל end), בדומה לפונקציה range בפייתון.

OUTPUT

גנרטורים יכולים להיות יעילים יותר מרשימות במצבים מסוימים, מכיוון שהם מחשבים את הערכים הבאים רק כאשר יש צורך בהם. זה עוזר לחסוך בזיכרון ובמחשוב מיותר. גנרטורים נפוצים במיוחד בעיבוד קבצים גדולים או בסטרימים של נתונים, שכן הם מאפשרים לנו לטפל בנתונים ביחידות קטנות ולא לשמור את כל הנתונים לזיכרון בבת אחת.

בשלב זה, חשוב להבין שגנרטורים אינם יוצרים רשימה או כל מבנה נתונים אחר, אלא הם מייצרים איטרטור על החישובים הנדרשים. כדי להמיר גנרטור לרשימה, ניתן להשתמש בפונקציה ()list ולהעביר את הגנרטור כארגומנט.

סיכמנו את המבוא לגנרטורים. כעת נמשיך לדוגמאות מעשיות ומורכבות יותר כדי להעמיק את ההבנה בנושא חשוב זה.

פייתון גנרטורים - דוגמאות נוספות

עכשיו, לאחר שהכרנו את הרעיון הבסיסי של גנרטורים, בואו נראה כמה דוגמאות יותר מורכבות ומעשיות לשימוש בהם.

דוגמה 1: מחולל פיבונאצ׳י (Fibonanci Generator)

סדרת Fibonacci היא סדרה חשובה ומעניינת במתמטיקה. כל מספר בסדרה הוא סכום שני המספרים הקודמים, החל מ-0 ו-1. הסדרה נראית כך: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

נכתוב גנרטור שמחזיר את ערכי סדרת פיבונאצ׳י:

1def fibonacci():
2 a, b = 0, 1
3 while True:
4 yield a
5 a, b = b, a + b

שימו לב שהגנרטור "זוכר" את הערכים הקודמים של a ו-b בכל פעם שהוא נקרא, ובאמצעות הקוד a, b = b, a + b אנו מחשבים את הערך הבא בסדרה.

שימו לב שfibonacci יכול לרוץ לנצח (תמיד יש את המספר הבא) על כן אי אפשר פשוט להחליף את fibonacci ברשימה רגילה.

הפעילו את הגנרטור fibonacci, והכניסו את 10 הערכים הראשונים לרשימה שתישמר במשתנה result_list. שימו לב ש

1list(fibonacci())

תיכשל כי במקרה הנוכחי הרשימה היא אינסופית וזה עלול להקריס לנו את המחשב.

OUTPUT

דוגמה 2: מחולל משתנים אקראיים (Random Variable Generator)

נניח שאנו רוצים ליצור משתנים אקראיים מתוך התפלגות נתונה. במקום ליצור רשימה גדולה של ערכים אקראיים מראש (דבר שעלול לצרוך הרבה זיכרון), נוכל להשתמש בגנרטור כדי ליצור ערכים חדשים רק כאשר יש צורך בהם.

1import random
2
3def random_variable(distribution):
4 while True:
5 yield random.choice(distribution)

הגנרטור random_variable מקבל התפלגות (לדוגמה, רשימה או קובץ) ומחזיר ערכים אקראיים מההתפלגות הזו ללא סוף. הוא עושה זאת באמצעות לולאה אינסופית והמילה השמורה yield.

בדומה לדוגמא הגדירו גנרטור random_variable זמנו אותו עם ההתפלגות [1, 2, 3, 4, 5], ושמרו את 10 התוצאות הראשונות ברשימה בשם result_list.

OUTPUT

דוגמה 3: מחולל ערכים פרימיטיביים (Primitive Value Generator)

לעתים קרובות, אנו רוצים ליצור רצף של ערכים פרימיטיביים (כמו מספרים שלמים, מספרים ממשיים או מחרוזות) על פי כלל מסוים. במקום ליצור רשימה גדולה מראש, נוכל להשתמש בגנרטור כדי ליצור את הערכים הללו רק כאשר יש צורך בהם.

1def integers(start, stop, step=1):
2 value = start
3 while value < stop:
4 yield value
5 value += step
6
7def floats(start, stop, step=0.1):
8 value = start
9 while value < stop:
10 yield value
11 value += step
12
13def strings(start, stop, step=1):
14 current = start
15 while ord(current) < ord(stop):
16 yield current
17 current = chr(ord(current) + step)

הגנרטורים integers, floats, ו-strings מחזירים ערכים שלמים, ממשיים ומחרוזות, בהתאמה, בתחום הערכים שהוגדר. הם משתמשים בלולאה while ובמילה השמורה yield כדי להחזיר ערכים חדשים בכל פעם שהם נקראים.

יצרו גנרטור integers עם הערכים מ-1 עד 10, שימרו את 5 הערכים הראשונים בmy_list.

OUTPUT

דוגמה 4: גנרטור למעבר על קבצים גדולים (File Iterator Generator)

גנרטורים הם כלי נפלא לטיפול בקבצים גדולים או בסטרימים של נתונים. במקום לקרוא את כל הקובץ לזיכרון בבת אחת, נוכל להשתמש בגנרטור כדי לקרוא את הקובץ שורה אחר שורה, ולבצע פעולות על כל שורה בנפרד.

1def file_iterator(file_path):
2 with open(file_path, 'r') as file:
3 for line in file:
4 yield line.strip()

הגנרטור file_iterator מקבל את נתיב הקובץ ומחזיר את כל השורות בקובץ, אחת אחר השנייה. הוא עושה זאת באמצעות לולאה for על הקובץ הפתוח, ומחזיר כל שורה באמצעות yield.

בדוגמאות אלו ראינו כמה שימושים שונים של גנרטורים, החל מיצירת רצפים של ערכים פרימיטיביים, דרך עיבוד קבצים גדולים, ועד לחישובים מתמטיים. גנרטורים הם כלי חזק ויעיל בפייתון, והם יכולים לסייע לנו בכתיבת קוד יעיל יותר ובשימוש נכון בזיכרון.

הצהרת נגישות

© 2022 DevIn. All rights reserved