( )map( ) filter – פונקציות מובנות ממעלה גבוהה
בפייתון קיימות פונקציות מובנות, שיודעות לקבל פונקציה, ואיטרטור (כמו רשימה למשל) ולבצע את הפעולה שהפונקציה יודעת לעשות, על כל אחד מהאיברים באיטרטור. התוצר שלהן הוא איטרטור המייצר בכל פעם את התוצאה של הכנסת האיבר הבא באיטרטור כפרמטר בפונקציה. יאללה דוגמא –
lista=[1,2,3,4,5] def func (num): return num**2 for i in map(func,lista): print (i)
>>>
1
4
9
16
25 print([i for i in map(func,lista)]) >>> [1, 4, 9, 16, 25] def func2(num): if num < 3: return False else: return True print([i for i in filter(func2,lista)]) >>> [3, 4, 5]
בתוכנית למעלה – נתבונן ראשית בפונקציה ()map שלוקחת פונקציה שקראנו לה func שמחזירה את ריבוע המספר שאנו מכניסים לפרמטר, ולוקחת רשימה שנקראת lista ומפעילה את הפונקציה על כל אחד מאיברי הרשימה. היות שהתוצר הוא איטרטור שבכל פעם מבצע את הפעולה על האיבר הבא ברשימה, כדי לראות את כל הרשימה עוברת תחת הפונקציה אנו זקוקים לפקודת for שתרוץ על האיטרטור שלנו ותשלוף את התוצר הבא בתור. אפשר לקבל את זה גם ברשימה באמצעות list comprehension ואפשר גם בדרכים אחרות. אפשרת גם לוותר על ()map לגמרי כפי שנראה בהמשך אבל קודם נראה מה פילטר, ()filter עושה. פילטר מסננת דרך הפונקציה רק תוצרים המוגדרים בפייתון כ – True ומוציאה החוצה תוצרים שהם False. לשם הדוגמא, נבנה פונקציה קטנה שמחזירה ערך של False למספרים הקטנים מ -3 ו- True למספר הגדולים או שווים ל- 3. כאשר נבצע פילטר של הפונקציה לרשימת המספרים שלנו lista נקבל רק את התוצרים המוגדרים לאחר הפעלת הפונקציה כ- True כלומר 3,4,5 וגם כאן היות שזה איטרטור אנו צריכים לבקש באופן מיוחד באמצעות פקודת for ו- list comprehension לקבל את כל תוצרי הסינון ברשימה מסודרת [3,4,5].
אפשר במקום ()map ופחות קוד להגיע לאותה תוצאה –
lista=[1,2,3,4,5] print([i**2 for i in lista])
>>>
[1, 4, 9, 16, 25]
lista=[1,2,3,4,5]
def func (num): if num%2==0: return num**2 else: return "kuku" print([func(i) for i in lista])
>>>
['kuku', 4, 'kuku', 16, 'kuku']
בדוגמא השנייה אנו רואים שאפשר גם כאשר הפונקציות מורכבות לבצע מיפוי בלי map() זה איטרטור אלא רשימה, ולכן יש הבדל בין השניים, אבל עושה פחות או יותר את אותה העבודה. כדאי לשים לב שאם לא היינו מבקשים בפונקציה השנייה להדפיס "kuku" כשהפרמטר הוא אי זוגי, היינו מקבלים None במקום, משום הפונקציה לא מחזירה כל ערך כאשר המספר אינו זוגי (num%2==0), כדי להימנע מכך היינו צריכים להוסיף תנאי if func(i)!=None ואז היינו מקבלים רשימה רק של ריבועי מספרים זוגיים [4,16] בלי מלל עודף.