כלי לייצור מספרים
range() עושה דבר אחד בדיוק: היא מייצרת רצף של מספרים שלמים. היא השותפה הקבועה של לולאות for כשצריך לחזור מספר מסוים של פעמים או לעבור על טווח מספרי.
הצורה הפשוטה ביותר מקבלת ארגומנט יחיד, ערך ה-stop:
פלט:
0
1
2
3
4
שני פרטים שתופסים מתחילים:
- הספירה מתחילה ב-0.
range(5)נותנת חמישה מספרים, החל מ-0. - ערך ה-stop אינו כלול.
range(5)עוצרת לפני 5, והיא לא כוללת את 5 עצמו.
הכללים האלה עקביים בכל פעולות ה-slicing, האינדקסים וה-range של Python. ברגע שמפנימים ש"stop אינו כלול", זה מפסיק להכשיל.
שלוש צורות
range() מקבלת ארגומנט אחד, שניים או שלושה:
step הוא גודל כל קפיצה. range(0, 20, 4) מייצרת כל מספר רביעי. זכרו את זה בפעם הבאה שתצטרכו "כל פריט שני" או "כל דגימה עשירית".
ספירה לאחור
ה-step יכול להיות שלילי, וזה מאפשר לספור לאחור:
שוב, ה-stop אינו כלול: range(10, 0, -1) עוצרת לפני 0, לא ב-0. כדי לכלול את 0, הגדירו את ה-stop ל--1:
range היא עצלה
ב-Python 3, range() לא בונה רשימת מספרים בזיכרון. היא מחזירה אובייקט range קל שמייצר מספרים אחד אחרי השני, לפי דרישה. לכן אפשר לכתוב:
"טווח" של מיליארד מספרים כמעט לא תופס זיכרון. המספרים נוצרים כשהלולאה מבקשת אותם.
אם אתם באמת צריכים רשימה של המספרים, כי אתם רוצים לשנות אותה, למיין אותה או לגשת לאינדקסים מעבר לבסיסי, המירו במפורש:
ברוב המקרים לא צריך את הרשימה. for i in range(...) עובדת ישירות.
דפוסים נפוצים
כמה מתכונים שתשתמשו בהם כל הזמן:
לעשות משהו n פעמים.
ה-_ הוא מוסכמה שפירושה "לא אכפת לי מהערך הזה". Python לא אוכפת אותה, אבל כל קורא יזהה את הכוונה.
גישה לרצף לפי אינדקס.
העדיפו enumerate() על פני range(len(...)), אבל כשצריך דווקא רק את האינדקס:
ועדיין, ברוב המקרים enumerate(items) נקייה יותר.
מעבר על כל איבר שני.
זה מדפיס a, c, e. עם זאת, ל-slicing פשוט, תחביר ה-slicing ישיר עוד יותר: items[::2].
ליצור רשימה מספרית מהירה.
זו list comprehension, שנסביר בהמשך, אבל range היא זו שמספקת את המספרים.
מה range() לא
שני קצוות חדים שכדאי להכיר:
rangeמייצרת רק מספרים שלמים. אם אתם צריכים צעדים עשרוניים (כמו מ-0.0 עד 1.0 בקפיצות של 0.1), השתמשו ב-numpy.arangeאו בלולאה עם מונה משלכם.rangeלא עובדת עם iterables כלשהם. היא מיועדת במיוחד למספרים שלמים. אם אתם מנסים לעבור עם "range" על רשימה, כנראה שאתם מחפשים אתenumerateאו פשוט את הרשימה עצמה.
הכול ביחד
דוגמה קטנה שמשתמשת בכמה וריאציות בבת אחת:
שתי לולאות מקוננות שמונעות על ידי range ומייצרות רשת. שימו לב ששתי הלולאות מתחילות ב-1, range(1, 6), כי אנחנו רוצים תוויות מ-1 עד 5.
ממשיכים לאוספים
ראיתם עכשיו תנאים, את שני סוגי הלולאות ואת range. זה מספיק בקרת זרימה כדי לעבוד עם כל אוסף. הפרק הבא: האוספים עצמם, רשימות, tuples, sets ו-dictionaries.
שאלות נפוצות
מה עושה range() ב-Python?
range() מייצרת רצף של מספרים שלמים. range(n) נותנת את 0 עד n-1. range(start, stop) נותנת מספרים שלמים מ-start ועד stop, בלי לכלול אותו. range(start, stop, step) מאפשרת לבחור את גודל הצעד, כולל צעדים שליליים לספירה לאחור.
האם range() יוצרת רשימה?
לא. ב-Python 3, range() מחזירה אובייקט range קל שמייצר מספרים לפי דרישה. זו הסיבה ש-range(10**9) מיידית: היא לא באמת מקצה מיליארד מספרים שלמים. עטפו אותה ב-list(...) אם אתם באמת צריכים רשימה.
איך סופרים לאחור עם range() ב-Python?
השתמשו בצעד שלילי: range(10, 0, -1) סופרת 10, 9, 8, ..., 1. זכרו שערך ה-stop תמיד אינו כלול, ולכן כדי לכלול את 0 תצטרכו range(10, -1, -1).