
while ו-yield. לולאת for מדפיסה את המספרים אחד אחרי השני.range בונה רשימה שלמה בזיכרון, ואילו הפונקציה עם yield מייצרת את הערך הבא רק כשצריך אותו. ההבדל נראה כשהטווח גדול מאוד.def my_range(start, stop): עם yieldgen = (x * x for x in lst)for num in (x * x for x in lst):הטקסט המלא של הדקות הראשונות בהרצאה «generators» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום לכולם, בשיעור הזה אנחנו נדבר על ג'נרטורס בפייתון אז מה זה ג'נרטורס? ג'נרטור זה קצת דומה לאיטרטור, אבל זה לא בדיוק ג'נרטור זה פונקציה שהיא כל פעם מג'נרטת את הערך הבא בואו ניתן דוגמה, נגיד אני רוצה לג'נרט את המספרים מ-5 עד טווח של מספרים
בואו נתחיל מטווח של מספרים אז def, בואו נקרא לזה my range היא מקבלת סטארט סטופ והיא עושה 4 in 4i in 4 שווה סטארט. בואו נכתוב את זה בצורה שגולה את while, while סטארט תתן קילד i ו-i פלוס שווה 1.
עכשיו אני לא בודק פה באמת שסטארט קטן לסטופ, זאת לא הכוונה, הכוונה היא לראות מה הדבר הזה עושה. 4 num in my range 10 עד 20, פרינט num.
קודם כל דבר ראשון כתבנו הרבה קוד, נריץ אותו, אחרי זה נדבר ונראה מה עשינו פה. אוקיי, יש לנו פה פונקציה, הדפסנו פה את כל המספרים, מ-10 עד 19.
אם הייתי רוצה עד 20, פשוט שווה. אוקיי, מה יש לנו פה? אז אנחנו בעצם for num, מספר בקריאה לפונקציה הזאת, תדפיס את num.
עכשיו, האם אתם רואים פה איפשהו ש-my range מחזירה מספר? לא, אני לא רואה פה לא return, היא לא יוצרת פה ליסט, הדבר היחיד שהיא עושה זה יילד, יילד איי, מה זה יילד?
דבר ראשון יילד זאת מילה שמורה, אתם רואים היא צבועה בכחול, זה אומר שזאת מילה שמורה, והמשמעות של יילד אומרת כזה דבר, פייתון רואה יילד, הוא עושה סטופ לריצה של הפונקציה הזאת, מחזיר את הערך שיש ביילד, לאחר מכן כשיש קריאה נוספת לפונקציה, הוא מריץ את הפונקציה מאותו מקום משורה אחרי הילד, כלומר, אם נסתכל על
הפלואו של הפונקציה שלנו, אז יש לנו מיי ריינג' 10, i שווה 10. בואו נראה את זה בדיבאגר, יהיה לנו באמת יותר קל להבין את זה. דבר ראשון, סתם בשביל הקטע, מה זה מיי ריינג'? לא בשביל הקטע, בשביל ההבנה.
אז מיי ריינג' הוא פונקציה. עכשיו, אם אני עושה a שווה מיי ריינג' 10 עד 20, מה הטייפ של a? הטייפ של a הוא ג'נרטור, שזה בעצם הנושא של השיעור שלנו.
עכשיו בואו נראה מה קורה פה, F5 או זה אותו דבר כמו סטפ אינטו, הגענו לפונקציה, פעם ראשונה אנחנו מתחילים את I שהוא יהיה שווה לסטארט, האם I קטן מ...
שימו לב, יש לנו את זה גם פה בצד ימין, התשובה היא כן, שים יילד ל-I, יצאנו החוצה, נם שווה ל-10, פסנו אותו, עכשיו חוקרים עוד פעם למיי ריינג', שימו לב לאן חזרנו, חזרנו ל-I שווה 1, כלומר, קראנו לפונקציה עוד פעם, אבל פייטון זוכר לאיפה לחזור, הוא לא קורא
לפונקציה עצמה, הוא קורא, הוא לא קורא לפונקציה מההתחלה, אלא הוא קורא לה מהשורה אחרי הילד. בואו נראה את זה שוב.
עוד פעם חוזר להולדת i, הפעם i שווה 11, יוצא החוצה, הוא מדפיס, חוזר, שורה אחרי הילד, וכן הלאה, וכן הלאה, וכן הלאה.
אז זה המילה יילד נותנת לנו. עכשיו, אם היינו רוצים לעשות את זה לא בצורה של ג'נרטור, פשוט היינו יכולים להחזיר. ריטרן, ריינג' של סטארט עד סטופ. בעצם ריינג' ואיקס ריינג' אולי עכשיו אפשר לגלות שאיקס ריינג' זה בעצם הדבר הזה.
איקס ריינג' הוא ג'נרטור שהוא מחזיר לנו כל פעם את הערך הבא בתור. עכשיו, מה ההבדל בעצם בין הילד לבין להחזיר פשוט ליסט של כולם? לכאורה הייתי יכול לעשות אם נפשט את זה פור נאם אין ואז, עוד פעם, לא בצורה כזאת, אבל 10, 11, 12 וכולי.
ההבדל הוא שבצורה הזאת יש לי פה הרבה שימוש בזיכרון שאני לא באמת צריך. הרי אני לא רוצה להשתמש בכל הליסט הזה. אני כל פעם, אני לא באמת צריך אותו לאחר כך. אני רוצה אותו עכשיו בשביל הלולאה, ואני גם לא צריך אותו את כולו, אני צריך רק איבר איבר.
בעצם הג'נרטור מאפשר לנו לחסוך במקום. אנחנו קוראים לפונקציה יותר פעמים, אבל מבחינת החיסכון במקום שהתוכנית שלי לוקחת היא לוקחת הרבה פחות מקום כי אני לא יוצר את כל הליסט בין הסטארט לסטופ אלא אני רק יוצר כל פעם את הערך הבא מתי זה טוב בוא נגיד ש-a שווה ל-range 10,000 ו-b שווה
ל-x range פרינט a פרינט b שימו לב כמה מקום היינו צריכים פה הקומפיילר עדיין עובד פה הוא עדיין לא סיים לרוץ הוא עדיין מריץ מריץ אז בואו נעצור את זה, קצת קפצתי פה מעל הפופיק.
בואו נתחיל מ-100. פרינט טייפ של A, פרינט טייפ של B. אז הפונקציה הראשונה החזירה לנו ריינג' ליסט.
פונקציה ריינג' החזירה לנו ליסט, כלומר בזיכרון עכשיו יש לי פה ליסט בגודל 100 שאני לא באמת צריך אותו. אולי כן, אולי לא, כרגע אני לא באמת צריך אותו.
הפונקציה השנייה לא לוקחת שום מקום בזיכרון, אני רק יצרתי ג'נרטור, כלומר יצרתי את הפונקציה הזאת וזהו, אין לי שום שימוש בזיכרון כמעט וזה בעצם היתרון של ג'נרטור.
עכשיו בואו רגע נכתוב ג'נרטור קצת יותר מתוחכם. בואו נגיד שאני רוצה כל פעם לקבל את המספר