שורה אחת, רעיון אחד
כבר כתבתם את הדפוס הזה כמה פעמים: מתחילים ברשימה ריקה, עוברים בלולאה על משהו, אולי מסננים, ומוסיפים לתוצאה עם append.
list comprehension אומרת את אותו הדבר בשורה אחת:
קראו את זה כך: "רשימה חדשה שמורכבת מ-n * 2, עבור כל n ב-numbers". המבנה הוא [expression for item in iterable].
זה לא טריק שייחודי ל-Python. זה נקרא comprehension כי אתם מתארים באופן הצהרתי מה נכנס לרשימה החדשה, במקום לכתוב את המכניקה של איך לבנות אותה.
הוספת סינון
הוסיפו פסוקית if אחרי חלק הלולאה כדי לסנן:
קראו את השנייה כך: "n * n עבור כל n ב-numbers, אבל רק אם n אי-זוגי".
הלולאה השקולה:
שתיהן בסדר. ה-comprehension קצרה יותר, ואחרי שקוראים כמה כאלה, גם קל יותר לסרוק אותה, כי הכוונה נמצאת שם בשורה אחת.
מיפוי וסינון יחד
אפשר להעביר ערכים דרך פונקציה ולסנן באותו זמן:
עבור כל מילה שארוכה מ-3 אותיות, מכניסים את הגרסה שלה באותיות גדולות.
לולאות מקוננות בתוך comprehension
שני for מייצרים זוגות בסגנון של מכפלה קרטזית:
הסדר זהה לסדר שהיה לכם אילו קיננתם את הלולאות: ה-for הראשון הוא החיצוני, והשני הוא הפנימי. זה נקרא משמאל לימין כמו הלולאה המוזחת השקולה.
שתי רמות הן בערך הגבול, ומעבר לזה לולאה רגילה קריאה יותר. אם הגעתם לשלוש, חזרו ללולאות.
Dict ו-Set Comprehensions
אותו רעיון, סוגריים אחרים:
set comprehensions נראות במבט ראשון זהות ל-dict comprehensions. ההבדל הוא key: value לעומת ביטוי יחיד. סוגריים מסולסלים עם : הם dict, סוגריים מסולסלים בלי : הם set.
Generator Expressions
כמעט תאום של list comprehension, אבל עם סוגריים עגולים במקום מרובעים, ובעיקר: היא לא בונה רשימה:
שימו לב שהעברנו את ה-generator ישירות ל-sum() ול-any(), בלי סוגריים נוספים. generator expressions הן הכלי הנכון כשמי שקורא להן צריך לעבור על הערכים פעם אחת בלבד. הן חסכוניות יותר בזיכרון מרשימה מלאה עבור אוספים גדולים.
מתי להשתמש בלולאה רגילה במקום
comprehensions מפתות. טכנית אפשר לדחוס לתוכן הרבה. לא כדאי.
העדיפו לולאה פשוטה כאשר:
- ההמרה היא יותר מצעד אחד. אם צריך משתני ביניים, כתבו אותה במלואה.
- יש טיפול מורכב בשגיאות או הסתעפויות.
- מי שקורא את השורה צריך לעצור יותר מפעם אחת כדי להבין אותה.
הכלל שאני מפעיל: אם אפשר לקרוא את ה-comprehension בנשימה אחת ולהבין מה היא עושה, היא נשארת. אם אני מועד, אני כותב אותה מחדש כלולאה.
יש comprehensions שנראות מתוחכמות אבל מזיקות:
אותה תוצאה. גרסת הלולאה היא חמש שורות במקום אחת, אבל "ארוך יותר" זה לא אותו דבר כמו "גרוע יותר".
כמה דפוסים שתשתמשו בהם שוב ושוב
חמשת הדפוסים האלה מכסים כמות מפתיעה של עבודה יומיומית עם נתונים.
הצעד הבא
ראיתם עכשיו את סוגי האוספים העיקריים ואת ה-comprehension שמחברת ביניהם. הפרק הבא: פונקציות, כלומר אריזת התנהגות ליחידות עם שם שאפשר להשתמש בהן שוב.
שאלות נפוצות
מה זה list comprehension ב-Python?
תחביר קומפקטי לבניית רשימה חדשה מתוך iterable קיים. [x * 2 for x in numbers] יוצרת רשימה חדשה שבה כל מספר מוכפל ב-2. אפשר גם לסנן: [x for x in numbers if x > 0].
מתי לא כדאי להשתמש ב-list comprehension?
כשהיא פוגעת בקריאוּת. אם הביטוי בפנים מסובך או מקונן לעומק, לולאת for רגילה עם שמות משתנים טובים ברורה יותר. comprehensions נועדו להמרות פשוטות: מיפוי וסינון. כל דבר מורכב יותר עדיף בלולאה מלאה.
מה ההבדל בין list comprehension ל-generator expression?
list comprehension בונה את כל הרשימה בזיכרון. generator expression (אותו תחביר, אבל עם סוגריים עגולים) מפיקה פריט אחד בכל פעם. השתמשו ב-generator כשמעבירים את התוצאות למשהו שעובר עליהן פעם אחת, כמו sum(...), כדי לא ליצור רשימה שתיזרק מיד.