16 באוגוסט 2021

Advanced Python - Iterator

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

נתחיל מהבסיס - איטרטור הוא למעשה כל אובייקט שניתן לעבור עליו בלולאה. אני מניח שאת האיטרטורים הבאים אתם בוודאי מכירים: List ו-Tuple. 

מי שמנוסה יודע שאפשר גם לבצע לולאה על Dictionary ועל Set למרות שהם Unordered Data Structure שהאובייקטים שבהם לא מקבלים index שזה אומר שלא בהכרח תקבלו את הסדר שתרצו כאשר תעברו עליהם בלולאה.

אבל האם ידעתם שאפשר גם להפוך כל אובייקט לאיטרטור אם תממשו בו פונקציות __iter__ עם __next__?

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

__iter__ יחזיר לנו את האובייקט עצמו, בתנאי שמימשנו בו את פונקציית __next__ .

__next__ יחזיר לנו את האיבר הבא ברשימה כאשר נבצע לולאה על האובייקט.

כדי לסמן שהגענו לסוף הרשימה, נעלה raise StopIteration.


לצורך ההמחשה, נציג מספר דוגמאות:

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

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

באותה מידה, יכולנו לבחור להחזיר מספר זוגי / אי-זוגי, מכפלה של מספרים או להתחיל ממספרים שליליים ולאו דווקא מאפס.

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

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


לסיכום


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

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




אין תגובות:

הוסף רשומת תגובה