לולאת for של Python היא "for each"
אם השתמשתם בשפה בסגנון C, לולאת for של Python תיראה לכם שונה. אין דפוס מונה של for (i = 0; i < n; i++). ה-for של Python היא לולאת for each לכל דבר: נותנים לה אוסף והיא מגישה את הפריטים אחד אחרי השני.
זה מדפיס שלוש שורות. Python קוראת את הרשימה, שולפת כל איבר בתורו וקושרת אותו ל-color בזמן שהגוף רץ. כשלא נשאר כלום, הלולאה מסתיימת.
שימו לב לצורה: for <name> in <iterable>: ואחריה גוף מוזח. הזחה, נקודתיים, גוף; אותו מבנה כמו if.
מה נחשב iterable
כמעט כל דבר שמחזיק רצף של ערכים. רשימות, tuples, מחרוזות, ranges, dicts, sets, קבצים ורוב האובייקטים המותאמים אישית שתבנו.
האחידות היא החלק הנחמד: תחביר אחד, צורות נתונים רבות.
ספירה עם range()
כשכן רוצים מונה, "תעשו את זה עשר פעמים" או "עברו על האינדקסים 0 עד 9", השתמשו ב-range():
זה מדפיס 0, 1, 2, 3, 4. range(stop) סופרת מ-0 ועד stop, לא כולל. range(start, stop) מאפשרת לקבוע ערך התחלה, ו-range(start, stop, step) מאפשרת לשלוט בגודל הצעד:
יש עמוד ייעודי על range בהמשך, כי שווה להבין אותה קצת יותר לעומק. בינתיים, range(n) נותנת n איטרציות שממוספרות מ-0 עד n-1.
enumerate ב-Python: לולאה עם אינדקס
צורך נפוץ: "אני רוצה את האינדקס ואת הערך יחד". האינסטינקט של מתחילים הוא להשתמש ב-range(len(...)), אבל ל-Python יש כלי נחמד יותר:
enumerate() מחזירה זוגות (index, value). שני המשתנים אחרי for מפרקים את הזוג לשני שמות: index ו-color. הרבה יותר נקי מ:
אם רוצים להתחיל לספור מ-1 במקום מ-0, העבירו start=1:
zip ב-Python: מעבר על שני רצפים יחד
כשיש שתי רשימות באותו אורך ורוצים לצמד ביניהן:
zip נעצרת ברצף הקצר ביותר. אם רוצים שהיא תמשיך ותמלא ב-None, השתמשו ב-itertools.zip_longest.
מעבר על dict
מילונים נותנים לכם לבחור על מה לעבור בלולאה:
רוב הזמן תרצו את .items(): מקבלים את המפתח ואת הערך יחד בשורה אחת קריאה.
break ו-continue
לפעמים רוצים לצאת מוקדם או לדלג על איטרציה.
break יוצאת מהלולאה מיד:
ברגע שנמצא מספר גדול מ-6, הלולאה נעצרת. מתעלמים משאר הפריטים.
continue מדלגת על שאר האיטרציה הנוכחית ועוברת לבאה:
מותר להשתמש בשתיהן, אם כי continue יכולה להקשות על מעקב אחרי הלולאה אם יש יותר מאחת. הרבה פעמים if/else פשוט נקרא טוב יותר.
פסקת else בלולאה
ל-Python יש פיצ'ר שאין ברוב השפות: פסקת else בלולאות. היא רצה כשהלולאה מסתיימת בלי להגיע ל-break.
שימושי, אבל מבלבל בהתחלה. אל תרגישו חובה להשתמש בזה: דגל בוליאני מחוץ ללולאה הוא הרבה פעמים ברור יותר לקוראים חדשים.
שינוי רשימה בזמן המעבר עליה
מלכודת אחת שכדאי לסמן: אל תוסיפו לרשימה ואל תסירו ממנה בזמן שאתם עוברים עליה בלולאה. האיטרציה מתבלבלת לגבי האינדקסים שעדיין תקפים, ואז או שמפספסים פריטים או שנתקלים בשגיאה. הדפוס הבטוח הוא לבנות רשימה חדשה:
או, כשתרגישו בנוח, list comprehension עושה את אותו הדבר בשורה אחת. נכסה את זה בפרק על אוספים.
דוגמה קטנה מקצה לקצה
נחבר כמה מהדברים האלה יחד: קריאת רשימה, סינון, enumerate והדפסה:
הבא בתור: לולאות while
for היא הבחירה הנכונה כשיודעים על מה עוברים. while היא הבחירה הנכונה כשחוזרים בלולאה עד שתנאי כלשהו משתנה, וזה מה שמגיע עכשיו.
שאלות נפוצות
איך עובדת לולאת for ב-Python?
for item in sequence: מריצה את הגוף המוזח פעם אחת לכל איבר ברצף, כש-item מקבל כל ערך בתורו. רצפים כוללים רשימות, tuples, מחרוזות, dicts, ranges וכל אובייקט שמגדיר איטרטור.
מה ההבדל בין break ל-continue?
break יוצאת מהלולאה מיד ומדלגת על כל האיטרציות שנותרו. continue מדלגת על שאר האיטרציה הנוכחית ועוברת לבאה. break נועדה ל"סיימתי"; continue נועדה ל"דלגו על זה".
איך עוברים בלולאה עם אינדקס ב-Python?
עטפו את הרצף ב-enumerate(...) כדי לקבל זוגות (index, value): for i, item in enumerate(items):. הרבה יותר נקי מלתחזק מונה משלכם עם i += 1 בסוף הלולאה.