פונקציות למדא (lambda) אנונימיות בפייתון
אחת התכונות הנפלאות של פייתון היא התחביר העשיר. שמצד אחד, מאפשר להגיע לאותה תוצאה במגוון דרכים אבל גם עלול להכשיל את המתכנתים החדשים שעלולים מהר מאוד להיתקל בתחביר לא מוכר בשעה שהם קוראים קוד שמישהו אחר כתב. אז במיוחד בשביל אותם מתכנתים חדשים, כתבתי מדריך שמסביר אודות פונקציות למדא, שנקראות גם פונקציות אנונימיות, פונקציות ללא שם, או ביטויי למדא.
לפונקציות רגילות יש שם
לפני שנלמד את הנושא של פונקציות אנונימיות בואו נזכיר לעצמנו כיצד עובדים עם פונקציה פייתונית רגילה שיש לה שם. לדוגמה, פונקציה שממירה את הטמפרטורה במעלות פרנהייט למעלות צלזיוס ועל כן נקרא את שמה f_to_c.
def f_to_c(x):
return (x-32)*5/9
אנו יכולים למפות כל פריט ברשימה של מעלות פרנהייט למעלות צלזיוס בצורה הפשוטה ביותר.
temps_f = [("New York",69.8),("Washington",75.2),("London",64.4)]
temps_c = []
for name, val in temps_f:
temps_c.append((name, f_to_c(val)))
print(temps_c)
[('New York', 21.0), ('Washington', 24.0), ('London', 18.000000000000004)]
ניתן להשתמש ב-list comprehensions ולקבל את אותה התוצאה באמצעות תחביר קצר בהרבה:
temps_c = [(name, f_to_c(val)) for (name, val) in temps_f]
print(temps_c)
[('New York', 21.0), ('Washington', 24.0), ('London', 18.000000000000004)]
ועכשיו, גבירותיי ורבותיי קבלו בבקשה את חתן השמחה פונקציית למדא אנונימית בפייתון.
פונקציות למדא אנונימיות
ביטוי למדא הוא פונקציה אנונימית קטנה.
הוא אנונימי כיוון אין לו בהכרח שם.
הוא קטן מכיוון שהוא יכול להכיל רק ביטוי אחד והוא חייב להשתרע ע"פ שורה אחת.
לדוגמה, ביטוי למבדה להמרת פרנהייט למעלות צלזיוס.
lambda x: (x-32) * 5/9
- מכריזים על למדא באמצעות מילת המפתח lambda
- אחריה יכול לבוא ארגומנט אחד או יותר
- אחרי רשימת הארגומנטים באים נקודתיים
- ואז בא הביטוי עצמו
כאשר אנו רוצים לקרוא לפונקציית lambda עלינו לתת לה שם. לדוגמה:
f_to_c = lambda x: (x-32)*5/9
print('The temp in London is {0:.2f}'.format(f_to_c(64.4)))
The temp in London is 18.00
ביטוי למדא יכול לקבל יותר מארגומנט אחד. במקרה שלפנינו, הביטוי מקבל שני ארגומטים. השני מציין את מספר האפסים אחרי הנקודה.
f_to_c = lambda x,dec: str(round((x-32)*5/9,dec))
print(f_to_c(70,2))
21.11
ביטוי למדא יכול לקבל ערך ברירת מחדל לארגומנטים שלו.
f_to_c = lambda x,dec=1: str(round((x-32)*5/9,dec))
print(f_to_c(70))
21.1
ביטויי למדא ורשימות
ניתן להפעיל ביטויי למדא על כל אחד מהפריטים שמרכיבים רשימה.
כדי לסדר רשימה בסדר א"ב (לקסיקוגרפי) אנחנו משתמשים בפונקציה sorted:
arr = ['za', 'xc', 'yb', ]
print(sorted(arr))
לפונקציה sorted אנחנו יכולים להעביר פונקציית למדא ולסדר באופן גמיש בהרבה. לדוגמה, נסדר את הפריטים על פי סדר א"ב של המחרוזות ההפוכות.
כדי להפוך מחרוזת אנחנו משתמשים ב-slicing:
print("A string"[::-1]) # prints 'gnirts A'
נעביר כל אחד מהפריטים במערך בתור פרמטר k לפונקצית למדא אשר תהפוך את המחרוזות, ואת המחרוזות ההפוכות נסדר באמצעות הפונקציה sorted:
arr = ['za', 'xc', 'yb', ]
print(sorted(arr, key=lambda k: k[::-1]))
התוצאה:
['za', 'yb', 'xc']
המקרה המיוחד של ביטויי למדא בתוך list comprehensions
ראינו בסעיף קודם שניתן להפעיל ביטויי למדא על כל אחד מהפריטים שמרכיבים רשימה.
בדוגמה להלן, נקרא לפונקציה מתוך מתוך list comprehension.
temps_c = [(name, f_to_c(val)) for (name, val) in temps_f]
print(temps_c)
[('New York', '21.0'), ('Washington', '24.0'), ('London', '18.0')]
נראה טוב. למה שלא נשתמש בביטוי הלמדא ישירות בתוך ה-list comprehension?
בוא ננסה להשתמש בביטוי הלמדא ישירות בתוך ה-list comprehensions.
temps_c = [lambda x: (x-32)*5/9 for (name, x) in temps_f]
print(temps_c)
[. at 0x7f8ed07e4400>, . at 0x7f8ed07e4598>, . at 0x7f8ed07e4488>]
וואי, וואי, וואי. מה זה? הרשימה של המקומות בזכרון שבתוכם מאוחסנות הפונקציות. זו לא טעות, אבל בטח שלא התוצאה המקווה.
כדי להפוך את הלמדא בתוך list comprehensions לפונקציה מתפקדת אנחנו צריכים להוסיף לקוד קצת תבלין. ובמקרה שלנו, התבלין הוא קארי. Currying (שפירושו המילולי הוא להוסיף קארי) אורז ביחד מספר פעולות וקצת מידע לפונקציה אמיתית. כך נראית הוספת קארי לביטוי הלמדא שלנו:
(lambda x: (x-32)*5/9)(x)
- תחמנו את הביטוי כולו בסוגריים
- הוספנו סוגריים מימין שבתוכם נציין את הפרמטרים לשימוש הפונקציה שיצרנו בצעד הקודם
ננסה את ה-currying על הקוד שלנו:
temps_c = [(lambda x: (x-32)*5/9)(x) for (name, x) in temps_f]
print(temps_c)
[21.0, 24.0, 18.000000000000004]
זה עובד גם על טופלים:
temps_c = [(name,(lambda x: (x-32)*5/9)(x)) for (name, x) in temps_f]
print(temps_c)
[('New York', 21.0), ('Washington', 24.0), ('London', 18.000000000000004)]
קצר יותר ולא בהכרח קריא יותר, אם כי תמצאו מתכנתים שמחבבים את הגרסה המקוצרת ביותר.
בעיניי, הגרסה הנוחה יותר להבנה כוללת 2 שורות. בשורת הראשונה פונקציית למדא, ובשורה השנייה קריאה לפונקציה.
f_to_c = lambda x: (x-32)*5/9
temps_c = [(name, f_to_c(val)) for (name, val) in temps_f]
לכל המדריכים בסדרה ללימוד פייתון
אהבתם? לא אהבתם? דרגו!
0 הצבעות, ממוצע 0 מתוך 5 כוכבים
המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.
למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.
שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.
המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?
השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.