You are on page 1of 33

‫תוכן עניינים‬

‫‪.............................‬‬
‫‪..........‬‬
‫‪3‬‬ ‫‪................................................................‬‬ ‫פרק ‪ _:1‬מבוא‬
‫‪..........................‬‬
‫‪....‬‬
‫‪3 ................................................................................................‬‬ ‫מהי ‪?Python‬‬
‫‪......................‬‬
‫‪3................................................................................................‬‬ ‫‪ Python‬לעומת ‪C‬‬
‫‪......................‬‬
‫‪3 ................................................................................................‬‬ ‫הפעלת ‪Python‬‬

‫‪.....................‬‬
‫‪5.. ................................‬‬ ‫פרק ‪ _:2‬ה‪ Interpreter-‬ומאחורי הקלעים‬
‫‪................................‬‬
‫‪................‬‬
‫‪5‬‬ ‫‪................................................................‬‬ ‫משחקים עם ה‪Interpreter-‬‬
‫‪...............................‬‬
‫‪.........‬‬
‫‪5‬‬ ‫‪................................................................‬‬ ‫משתנים והשמות (‪)Assignments‬‬
‫‪.................‬‬
‫‪................................‬‬
‫‪7‬‬ ‫‪................................................................‬‬ ‫איך ‪ Python‬עובד (מימוש)‬

‫‪............................‬‬
‫‪.........‬‬
‫‪8‬‬ ‫‪................................‬‬ ‫פרק ‪ _:3‬טיפוסי נתונים ואופרטורים‬
‫‪...............................‬‬
‫‪.........‬‬
‫‪8‬‬ ‫‪................................................................................................‬‬ ‫מספרים‬
‫‪................................‬‬
‫‪........‬‬
‫‪10‬‬ ‫‪................................................................................................‬‬ ‫מחרוזות‬
‫‪........................‬‬
‫‪................................‬‬
‫‪11‬‬ ‫‪................................................................‬‬ ‫מחרוזות ‪Unicode‬‬
‫‪................................‬‬
‫‪........‬‬
‫‪11‬‬ ‫‪................................................................................................‬‬ ‫רשימות‬
‫‪................................‬‬
‫‪...........‬‬
‫‪12‬‬ ‫‪................................................................................................‬‬ ‫‪Tuples‬‬
‫‪................................‬‬
‫‪.........‬‬
‫‪13‬‬ ‫‪................................................................................................‬‬ ‫מילונים‬

‫‪.....................‬‬
‫‪15‬‬‫‪................................................................‬‬ ‫פרק ‪ _:4‬בקרת זרימה‬
‫‪..................‬‬
‫‪................................‬‬
‫‪15‬‬ ‫‪................................................................................................‬‬ ‫‪if‬‬
‫‪................................‬‬
‫‪............‬‬
‫‪15‬‬ ‫‪................................................................................................‬‬ ‫‪while‬‬
‫‪................‬‬
‫‪................................‬‬
‫‪15‬‬ ‫‪................................................................................................‬‬ ‫‪for‬‬
‫‪.........................‬‬
‫‪17. ................................................................................................‬‬ ‫‪range, xrange‬‬
‫‪........................‬‬
‫‪18................................................................................................‬‬ ‫‪break, continue‬‬
‫‪................................‬‬
‫‪.............‬‬
‫‪18‬‬ ‫‪................................................................................................‬‬ ‫‪pass‬‬

‫‪.....................‬‬
‫‪19 ................................................................‬‬ ‫פרק ‪ _:5‬קלט ופלט‬
‫‪........................‬‬
‫‪19‬‬‫‪................................................................................................‬‬ ‫הדפסה למסך‬
‫‪........................‬‬
‫‪................................‬‬
‫‪19‬‬ ‫‪................................................................‬‬ ‫קלט מהמקלדת‬
‫‪................................‬‬
‫‪..........‬‬
‫‪19‬‬ ‫‪................................................................................................‬‬ ‫קבצים‬

‫‪.......................‬‬
‫‪21.. ................................................................‬‬ ‫פרק ‪ _:6‬פונקציות‬
‫‪........................‬‬
‫‪................................‬‬
‫‪21‬‬ ‫‪................................................................‬‬ ‫הגדרת פונקציות‬
‫‪........................‬‬
‫‪21‬‬
‫‪................................................................................................‬‬ ‫‪ pass‬בפונקציות‬
‫‪..............................‬‬
‫‪......‬‬
‫‪21‬‬ ‫‪................................................................................................‬‬ ‫פרמטרים‬
‫‪................................‬‬
‫‪...........‬‬
‫‪23‬‬ ‫‪................................................................................................‬‬ ‫תיעוד‬
‫‪.......................‬‬
‫‪................................‬‬
‫‪23‬‬ ‫‪................................................................‬‬ ‫משתנים בפונקציות‬
‫‪................................‬‬
‫‪.............‬‬
‫‪24‬‬ ‫‪................................................................‬‬ ‫החזרת ‪-Tuple‬ים מפונקציה‬

‫‪.............................‬‬
‫‪........‬‬
‫‪25‬‬ ‫‪................................‬‬ ‫פרק ‪map, reduce, filter, lambda_:7‬‬
‫‪................................‬‬
‫‪..............‬‬
‫‪25‬‬ ‫‪................................................................................................‬‬ ‫‪map‬‬
‫‪................................‬‬
‫‪..........‬‬
‫‪25‬‬ ‫‪................................................................................................‬‬ ‫‪reduce‬‬
‫‪................................‬‬
‫‪.............‬‬
‫‪25‬‬ ‫‪................................................................................................‬‬ ‫‪filter‬‬
‫‪................................‬‬
‫‪..........‬‬
‫‪26‬‬ ‫‪................................................................................................‬‬ ‫‪lambda‬‬
‫‪...........................‬‬
‫‪26‬‬
‫‪... ................................................................‬‬ ‫שימוש ב‪ reduce ,map-‬ו‪ filter-‬ביחד‬
‫‪........................‬‬
‫‪................................‬‬
‫‪27‬‬ ‫‪................................................................‬‬ ‫מילה על יעילות‬

‫‪........................‬‬
‫‪28‬‬‫‪... ................................................................‬‬ ‫פרק ‪ _:8‬מודולים‬
‫‪...........................‬‬
‫‪28‬‬
‫‪... ................................................................................................‬‬ ‫מהו מודול?‬
‫‪.........................‬‬
‫‪28. ................................................................‬‬ ‫אוסף פונקציות שנמצא בקובץ אחר‬
‫‪..............................‬‬
‫‪......‬‬
‫‪29‬‬ ‫‪................................................................‬‬ ‫הרצת קבצי ‪ Python‬כמו תוכניות‬
‫‪................................‬‬
‫‪...............‬‬
‫‪29‬‬ ‫‪................................................................‬‬ ‫כתיבת מודולים של ממש‬
‫‪................‬‬
‫‪................................‬‬
‫‪30‬‬ ‫‪................................................................‬‬ ‫מודולים מובנים ב‪Python-‬‬
‫‪................‬‬
‫‪................................‬‬
‫‪30‬‬ ‫‪................................................................................................‬‬ ‫‪dir‬‬
‫‪.....................‬‬
‫‪................................‬‬
‫‪31‬‬ ‫‪................................‬‬ ‫פרק ‪ :_9‬ספריות נפוצות‬
‫‪.............................‬‬
‫‪.....‬‬
‫‪31‬‬ ‫‪................................................................................................‬‬ ‫‪os‬‬ ‫ספריית‬
‫‪...........................‬‬
‫‪32‬‬
‫‪... ................................................................................................‬‬ ‫‪sys‬‬ ‫ספריית‬
‫‪........................‬‬
‫‪32 ................................................................................................‬‬ ‫‪string‬‬ ‫ספריית‬
‫‪.........................‬‬
‫‪32. ................................................................................................‬‬ ‫‪math‬‬ ‫ספריית‬
‫פרק ‪_:1‬מבוא‬
‫מהי ‪?Python‬‬
‫‪ Python‬נוצרה בשנות ה‪90 -‬‬ ‫‪ Python‬היא שפת ‪ Scripting‬נוחה לשימוש שהפכה למאוד פופולרית בשנים האחרונות‪.‬‬
‫המוקדמות ע"י גידו ואן רוסם ( ‪ )Guido van Rossum‬ב‪ ,Stichting Mathematisch Centrum -‬כשפת המשך לשפה שנקראה‬
‫‪ .ABC‬בשנת ‪ 1995‬גידו המשיך את פיתוח בחברה ששמה ‪ ,)CNRI ( Corporation for National Research Initiatives‬ואף‬
‫‪ 2000‬גידו וצוות הפיתוח של ‪ Python‬עברו ל‪ BeOpen.com -‬כדי לייסד את‬ ‫הוציא מספר גירסאות של השפה‪ .‬במאי‬
‫‪Python Software‬‬ ‫"‪ ."BeOpen Python Labs team‬באוקטובר ‪ 2000‬בצוות עבר ל‪ ,Digital Creations -‬וב‪ 2001 -‬נוסד‬
‫‪ ,)PSF ( Foundation‬שהוא ארגון ללא מטרות רווח‪ Digital Creations .‬היא אחת המממנות של ‪ .PSF‬כל מה שקשור ל ‪-‬‬
‫‪ Python‬הוא ‪ ,Open Source‬כלומר הקוד פתוח ונגיש לכולם‪ ,‬ולכל אחד מותר לבצע בו שינויים ולהפיצו מחדש‪ .‬אתר‬
‫הבית של ‪ PSF‬הוא ‪.http://www.python.org/psf/‬‬
‫כאשר אומרים "שפת ‪ "Scripting‬מתכוונים שאין צורך בהידור ( ‪ )Compilation‬וקישור ( ‪ )Linkage‬של תוכניות‪ .‬ב‪Python -‬‬
‫פשוט כותבים ומריצים‪ .‬כל סביבת עבודה של ‪ Python‬מגיעה עם ‪ Interpreter‬שמאפשר כתיבה ישירה של פקודות אליו‪,‬‬
‫אפילו בלי צורך לכתוב תוכנית או קובץ‪ .‬בצורה כזו מאוד נוח להתנסות בשפה‪ ,‬לבצע חישובים מהירים (עוד תכונה חזקה‬
‫של ‪ )Python‬ולבדוק דברים קטנים במהירות‪ ,‬בלי הצורך לכתוב תוכנית שלמה‪.‬‬
‫ל ‪ Python‬יתרונות רבים על פני שפות ‪ Scripting‬אחרות‪ .‬ראשית‪ Python ,‬פשוטה בהרבה ללימוד‪ ,‬לקריאה ולכתיבה‬
‫משפות אחרות (שחלקן מתעללות במתכנת ובמי שצריך לקרוא קוד כתוב)‪ Python .‬גורמת לקוד שכתוב בה להיראות‬
‫מסודר‪ ,‬ברור ומובנה (נראה כיצד מאוחר יותר)‪ .‬מודל המימוש של השפה ברור בהרבה ממימוש שפות אחרות‪ ,‬ובכך‬
‫תורם להבנת השפה ולשליטה בה‪.‬‬
‫שנית‪ Python ,‬מכיל בתוכו אוסף מכובד מאד של ספריות סטנדרטיות‪ ,‬כלומר ספריות שניתן להסתמך על קיומן בכל‬
‫‪ ,)zip‬תכנות לתקשורת‬ ‫מימוש של ‪ .Python‬בין הכלים השימושיים ניתן למצוא יכולות התמודדות עם קבצים דחוסים (‬
‫‪ ,TCP/IP‬כלים מרובים לתכנות בסביבת האינטרנט‪ ,‬ממשק משתמש גרפי ( ‪ ,)GUI‬ספריות לטיפול בטקסט ומחרוזות (כמו‬
‫כן עיבוד טקסטואלי למיניו)‪ ,‬עבודה עם פונקציות מתקדמות של מערכת ההפעלה‪ ,‬תמיכה בתכנות מבוזר ( ‪Distributed‬‬
‫‪Python‬‬ ‫‪ ,)Development‬יכולת טיפול אינטנסיבית בקבצי ‪ XML‬ונגזרותיהם‪ ,‬ועוד הרבה הרבה הרבה דברים! כמו כן‬
‫מטפלת במידע בינארי (מידע שאינו טקסטואלי) בצורה הרבה יותר טובה משפות מתחרות‪.‬‬
‫בנוסף‪ ,‬כמו שניתן לכתוב תוכניות קטנות ב‪ ,Python -‬קיימים בה כלים לכתיבת תוכניות גדולות‪ ,‬ואף מודולים שלמים‪.‬‬
‫‪ Python‬תומכת בתכנות מכוון עצמים ( ‪ ,)OOP‬חריגות ( ‪ ,)Exceptions‬מבני נתונים ( ‪ )Data Structures‬וקישוריות גם ל‪ ,C -‬או‬
‫כל שפה שניתן לקרוא לה מ‪.C-‬‬
‫דבר נוסף שכדאי לדעת על ‪ Python‬הוא שיש לה מספר גרסאות‪ .‬אמנם יש תאימות לאחור‪ ,‬אבל בגרסאות החדשות‬
‫(‪ 2.0‬ומעלה) יש הרבה תכונות חדשות ונוחות לשימוש‪ .‬בחוברת זו נלמד את גרסה ‪( 2.2‬גרסה ‪ 2.3‬יצאה לאוויר העולם‬
‫בזמן כתיבת שורות אלה ממש)‬

‫לסיכום – ‪ Python‬היא כלי רב‪-‬עצמה בידיו של כל מתכנת המכבד את עצמו!‬

‫‪ Python‬לעומת ‪C‬‬
‫אוקיי‪ ,‬אז ‪ Python‬היא שפה מגניבה שמאפשרת לעשות הרבה דברים בקלות ובמהירות‪ ,‬לא צריך להסתבך עם‬
‫קומפיילרים ולינקרים ואפילו אפשר לא לכתוב את התוכניות בקבצים אם רוצים‪ .‬אבל‪ ,‬זה לא אומר שמפסיקים‬
‫להשתמש ב‪:C-‬‬
‫בראש ובראשונה‪ Python ,‬היא שפת ‪ – Scripting‬מה שאומר ש‪ Python -‬רצה לאט יותר מ‪ .C -‬כאשר נעדיף ביצועים על‬
‫מהירות כתיבת הקוד (או נוחות הכתיבה)‪ ,‬נשתמש ב‪ ,Pascal ,C -‬או כל שפה מקומפלת אחרת‪ .‬בנוסף‪ ,‬ניתן לכתוב‬
‫מודולי הרחבה ל‪ Python-‬באמצעות ‪ C‬ו‪ ,C++-‬ולכן שפות אלה הן בעלות שימוש רב גם בעת העבודה עם ‪.Python‬‬

‫הפעלת ‪Python‬‬
‫דבר אחרון שנעשה במבוא המצומצם שלנו הוא להפעיל את ‪.Python‬‬
‫כיום‪ Python ,‬מופצת יחד עם כל ה‪-Distribution -‬ים הפופולריים של ‪ ,RedHat, Slackware, Corel, Debian ( Linux‬ועוד‪,)...‬‬
‫וניתן להוריד סביבות פיתוח של ‪ Python‬ל‪( Windows-‬למשל ‪ ActivePython‬של ‪ ,ActiveState‬גירסה ‪ 2.2‬ומעלה)‪.‬‬

‫כמו כן‪ ,‬ניתן לבקר באתר ‪ www.python.org‬ולמצוא שם גרסאות מוכנות ל – ‪ Windows‬כולל התקנה נוחה ופשוטה‪.‬‬

‫‪ python‬מהלינוקס‬ ‫שימו לב ‪ :‬הנכם מקבלים‪ ,‬בנוסף לחוברת זו‪ ,‬גם חוברת ודיסק של לינוקס‪ .‬ניתן להפעיל את‬
‫שקיבלתם‪.‬‬

‫כדי להפעיל את ‪ Python‬בלינוקס‪ ,‬פשוט מקלידים את הפקודה ‪ python‬ב‪ console-‬ומקבלים את ה‪ prompt-‬של ‪:Python‬‬

‫‪$ python‬‬
‫)‪Python 2.2.1 (#2, May 1 2002, 17:17:17‬‬
‫‪[GCC 2.95.2 19991024 (release)] on shrubbery‬‬
‫‪Type “help”, “copyright”, “credits” or “license” for more information.‬‬
‫>>>‬

‫כדי להפעיל את ‪ Python‬מחלונות‪ ,‬צריך כמובן להתקין את אחת מסביבות העבודה שקיימות כיום לחלונות‪ .‬אם התקנת‬
‫את הסביבה המצויינת למעלה‪ ,‬ניתן להפעיל את הסביבה מ‪Start  Programs  ActiveState ActivePython  Python -‬‬
‫‪.Interpreter Shell‬‬
‫במהלך כל החוברת‪ ,‬הדוגמאות שיירשמו יילקחו מסביבת העבודה בלינוקס‪ ,‬אבל אין שום הבדל בין שתי סביבות‬
‫העבודה (בהנחה שעובדים עם גירסה עדכנית – ‪ 2.2‬ומעלה)‪.‬‬

‫חשוב מאוד! חוברת זו מלמדת את גירסה ‪ 2.2‬של ‪ ,Python‬ולכן כאשר אתם מורידים גירסה של ‪ ,Python‬יש לבדוק שזו‬
‫גירסה ‪ 2.2‬ומעלה‪.‬‬
‫פרק ‪_:2‬ה‪ Interpreter-‬ומאחורי הקלעים‬
‫משחקים עם ה‪Interpreter-‬‬
‫אחרי שהפעלנו את ‪ ,Python‬הגיע הזמן להתחיל לשחק איתו קצת‪...‬‬
‫בהנחה שהפעלת את התוכנה הנכונה‪ ,‬על המסך מופיע ה‪ prompt -‬של ‪ – Python‬סימן של שלושה חיצים‪:‬‬

‫>>>‬

‫ב‪ prompt-‬הזה ניתן למעשה לכתוב כל פקודת ‪ ,Python‬והיא תורץ כל עוד היא חוקית ותקינה‪.‬‬
‫אבל הדבר הראשון שננסה הוא לא פקודה‪ ,‬אלא ביטוי‪ .‬נרשום את הביטוי ‪:1+1‬‬

‫‪>>> 1+1‬‬
‫‪2‬‬

‫הביטוי נכון‪ ,‬אבל זה לא ממש מרשים‪ ...‬אמרנו של‪ Python-‬יש יכולות חישוב מהירות‪ .‬בואו ננסה משהו קצת יותר מסובך‪:‬‬

‫‪>>> 2L**2**2**2**2‬‬

‫‪ 2L‬במקום ‪ 2‬רגיל) יופיע בפרק על טיפוסי‬ ‫את התוצאה כבר לא נרשום כאן‪ ...‬הסבר מלא על השורה (ולמה רשמנו‬
‫נתונים‪ .‬אם הרצת את השורה האחרונה על המחשב שלך‪ ,‬לקח לו כמה שניות להגיע לתוצאה‪ ,‬אבל הוא כתב על המסך‬
‫ממש הרבה מספרים‪ .‬מה שעשינו בשורה האחרונה היה‪:‬‬

‫וכמו שבוודאי הבנת‪ ** ,‬זה חזקה‪.‬‬


‫‪ Python‬יודע גם לטפל במחרוזות‪ :‬מחרוזות נכתבות כרצף של תווים בין שני תווים של גרש בודד ( ' )‪ ,‬או בין שני תווים‬
‫של גרשיים (")‪ .‬כמובן‪ ,‬אי‪-‬אפשר לשלב (מחרוזת שנפתחת בגרש אחד ונסגרת בגרשיים)‪.‬‬

‫‟!‪>>> „Hello, World‬‬


‫‟!‪„Hello, World‬‬

‫עוד על מחרוזות וכל הדברים שניתן לעשות בהן‪ ,‬בפרק הבא‪.‬‬


‫‪ )Underscore‬ב‪ Python-‬מציין את התוצאה האחרונה שחושבה ע"י ה‪-‬‬ ‫הדבר האחרון שנלמד הוא _‪ .‬סימן ה _ (‬
‫‪ .Interpreter‬כך למשל‪:‬‬

‫>>>‬ ‫‪1+1‬‬
‫‪2‬‬
‫>>>‬ ‫‪_+2‬‬
‫‪4‬‬
‫>>>‬ ‫_‬
‫‪4‬‬
‫>>>‬ ‫‪_**2‬‬
‫‪16‬‬

‫משתנים והשמות (‪)Assignments‬‬


‫כמו ברוב שפות‪-‬התכנות‪ ,‬גם ב‪ Python-‬יש משתנים‪ .‬אבל‪ ,‬שלא כמו בכל שפת תכנות‪ ,‬ב‪ Python-‬אין צורך להכריז על‬
‫משתנים או על הסוג שלהם‪.‬‬
‫ב‪ ,Python-‬משתנה נוצר כאשר מציבים לתוכו ערך‪ ,‬וסוג המשתנה נקבע לפי הסוג של אותו ערך התחלתי‪ .‬דוגמה‪:‬‬

‫‪>>> x=5‬‬
‫)‪>>> type(x‬‬
‫>‟‪<type „int‬‬

‫בדוגמה הזאת נוצר משתנה בשם ‪ ,x‬וערכו ההתחלתי הוא ‪ .5‬כיוון ש‪ 5 -‬הוא מספר שלם (יש לשים לב להבדל בין ‪ 5‬ל‪-‬‬
‫‪ ,5.0‬כמו ב‪ )C-‬סוג המשתנה הוא ‪.int‬‬
‫את סוג המשתנה מקבלים באמצעות הפונקצייה המובנית ‪ ,type‬המקבלת בסוגריים את המשתנה ומחזירה את הסוג‬
‫שלו‪.‬‬
‫כאשר מציבים למשתנה ערך חדש‪ ,‬גם סוג המשתנה מתעדכן בהתאם‪ .‬אם ‪ x‬היה ‪ int‬עד עכשיו‪ ,‬ונציב לתוכו ערך חדש‪,‬‬
‫סוג המשתנה ישתנה בהתאם לערך החדש‪:‬‬
‫‪>>> x=5.0‬‬
‫)‪>>> type(x‬‬
‫>‟‪<type „float‬‬

‫ועכשיו הסוג של ‪ x‬הוא ‪.float‬‬


‫אילוצי שמות המשתנים עובדים כמו ב‪:C-‬‬

‫‪>>> x=5‬‬
‫‪>>> y=x‬‬
‫‪>>> y‬‬
‫‪5‬‬

‫ואפילו ניתן ליצור השמות מרובות בשורה אחת‪:‬‬

‫‪>>> x, y = 17, 42‬‬


‫‪>>> x‬‬
‫‪17‬‬
‫‪>>> y‬‬
‫‪42‬‬

‫בנוסף‪ ,‬כדי להדפיס ערך של משתנה‪ ,‬ניתן להשתמש בפקודה ‪( print‬זה כבר שימושי בתוך תוכניות‪ ,‬לא ב‪:)Interpreter-‬‬

‫‪>>> print x‬‬


‫‪17‬‬

‫הפקודה ‪ ,print‬בנוסף לפקודות אחרות (יש להבדיל בין פקודות לבין פונקציות) מופיעה ללא סוגריים‪ .‬זאת משום שזו‬
‫פקודה ולא פונקציה‪ .‬ההבדל בין פונקציה לפקודה הוא שפקודה היא כל מילת מפתח של ‪ Python‬שאיתה כותבים את‬
‫בקרת הזרימה של התוכנית (הכוונה לפקודות ‪ ,print ,while ,if‬וכו')‪ .‬פונקציה היא אוסף של פקודות‪ ,‬פונקציות אחרות‬
‫ופונקציות מובנות שאותן אספנו ביחד כדי ליצור פעולה בסיסית‪.‬‬

‫נקודה נוספת שיש לציין היא ש‪ Python -‬היא ‪ ,Case-Sensitive‬כלומר יש הבדל בין משתנה בשם ‪ a‬לבין משתנה בשם ‪– A‬‬
‫אלו הם שני משתנים שונים‪ ,‬משום שהאות ‪ A‬איננה האות ‪ .a‬חוקים אלה הם כמו החוקים של ‪.C‬‬
‫בנוסף לטיפוסים המוכרים ב‪ ,C -‬ב‪ Python-‬יש מספר טיפוסים מובנים ( ‪ )Built In‬נוספים (את כולם נסקור בפרק הבא)‪.‬‬
‫אחד מהם הוא רשימה‪ .‬יצירה רשימה נעשית באופן הבא‪:‬‬

‫]‪>>> l = [1, 2, 3‬‬

‫כעת יש רשימה בשם ‪( l‬האות ‪ L‬קטנה) שמכילה את המספרים ‪ .3 ,2 ,1‬האינדקס של האיבר הראשון הוא אפס‪ ,‬וניתן‬
‫להתייחס לרשימה כולה או לאיבר בודד בה‪:‬‬

‫‪>>> l‬‬
‫]‪[1, 2, 3‬‬
‫]‪>>> l[0‬‬
‫‪1‬‬

‫סקירה מלאה של הרשימה ושאר הטיפוסים המובנים נמצאת בפרק הבא‪.‬‬


‫איך ‪ Python‬עובד (מימוש)‬
‫‪ ,Python‬אלא‬ ‫‪ .Python‬אין הדבר אומר שיש רק דרך אחת לממש את‬ ‫סעיף זה מתאר את דרך המימוש המקובלת של‬
‫שזוהי הדרך המקובלת לממש את ‪.Python‬‬
‫המשתנים ב‪ Python-‬הם לא יותר מאשר מצביעים – כל משתנה הוא מצביע לאובייקט‪ .‬לכל אובייקט יש סוג (אובייקט‬
‫של מספר‪ ,‬אובייקט של מחרוזת‪ ,‬וכד')‪ .‬משום שמשתנה הוא מצביע‪ ,‬נוח לשנות "ערכים" של משתנים – רק משנים את‬
‫העצם אליו המשתנה מצביע‪ ,‬וה"ערך" שלו משתנה‪.‬‬
‫כאשר משתנה מצביע לעצם‪ ,‬ויוצרים השמה למשתנה אחר (ע"י ‪ ,)x=y‬יוצרים הצבעה חדשה אל העצם‪ ,‬ולא עצם חדש‪.‬‬
‫כאשר משנים את העצם המקורי‪ ,‬כל מי שהצביע אליו מושפע‪ .‬בדוגמה הבאה ניצור רשימה‪ ,‬וננסה להשים אותה‬
‫למשתנה אחר‪:‬‬

‫>>>‬ ‫]‪x = [1, 3, 7‬‬


‫>>>‬ ‫‪y = x‬‬
‫>>>‬ ‫‪x‬‬
‫‪[1,‬‬ ‫]‪3, 7‬‬
‫>>>‬ ‫‪y‬‬
‫‪[1,‬‬ ‫]‪3, 7‬‬
‫>>>‬ ‫‪x[1] = 6‬‬
‫>>>‬ ‫‪x‬‬
‫‪[1,‬‬ ‫]‪6, 7‬‬
‫>>>‬ ‫‪y‬‬
‫‪[1,‬‬ ‫]‪6, 7‬‬

‫כפי שניתן לראות‪ ,‬יצרנו רשימה במשתנה ‪ ,x‬והשמנו אותה למשתנה ‪ .y‬כתוצאה מכך‪ ,‬לא נוצרה רשימה חדשה‪ ,‬אלא‬
‫הצבעה לרשימה הקיימת‪ .‬כאשר שינינו את הרשימה הקיימת‪ ,‬כל מי שהצביע אליה הושפע מכך‪.‬‬
‫פרק ‪_:3‬טיפוסי נתונים ואופרטורים‬
‫מספרים‬
‫אז נתחיל ממספרים‪ ,‬הטיפוס הפשוט ביותר‪ .‬מספר יכול להיות שלם‪ ,‬עשרוני או ארוך‪ ,‬כאשר יש הבדל ברור בין שלושת‬
‫סוגי המספרים‪ ,‬ולכל‪-‬אחד מהסוגים האלה יש ‪ type‬מיוחד משלו‪ .‬ה‪ type -‬של מספר שלם הוא ‘ ‪ ,’int‬ה‪ type -‬של מספר‬
‫עשרוני הוא ‘ ‪ ’float‬וה‪ type -‬של מספר ארוך הוא ‘ ‪( ’long int‬הכוונה ב‪ type -‬היא לסוג המשתנה שמוחזר ע"י הפונקצייה‬
‫המובנית )(‪.)type‬‬
‫מספרים שלמים הם אותם משתני ‪ 32-bit‬בעלי סימן מ‪ .C-‬הגבול שלהם הוא ‪ +2,147,483,647‬עד ‪.-2,147,483,648‬‬
‫מספר שלם הוא כל מספר שלם שאין לו תוספות אחריו (שבר עשרוני‪ ,‬או אותיות בעלות משמעות‪ ,‬אותן נראה בהמשך)‬
‫ושאינו חורג מהתחום הנ"ל‪ .‬אם מנסים להכריז על מספר שלם שחורג מהתחום‪ ,‬מוצגת הודעה שגיאה‪:‬‬

‫‪>>> 4389678923476892347‬‬
‫‪OverflowError: integer literal too large‬‬

‫כמו כן‪ ,‬אם כבר קיים משתנה שלם ומנסים לחשב באמצעותו ערך שחורג מהתחום של משתנה שלם‪ ,‬גם אז מוצגת‬
‫הודעת שגיאה‪:‬‬

‫‪>>> 2**30‬‬
‫‪1073741824‬‬ ‫הסבר‪ :‬חישבנו את ‪ 2‬בחזקת ‪ ,30‬ועל‪-‬ידי כך הפכנו את‬
‫‪>>> _*2‬‬ ‫המשתנה המחזיק את התוצאה האחרונה ( _ ) להיות מספר‬
‫‪Traceback (most recent call last):‬‬ ‫שלם רגיל שמחזיק את ‪ 2‬בחזקת ‪.30‬‬
‫? ‪File “<stdin>”, line 1, in‬‬ ‫כאשר ניסינו להכפיל אותו ב‪ ,2 -‬כלומר לחשב את ‪ 2‬בחזקת‬
‫‪OverflowError: integer multiplication‬‬ ‫‪ ,31‬התרחש ‪ Overflow‬בגלל חריגה מהתחום המותר‪.‬‬

‫‪ Overflow‬ויצירת‬ ‫כלומר‪ ,‬מספרים שלמים מתנהגים כמו ב‪ C -‬מבחינת גבולות וייצוג‪ ,‬למרות שיש הגנות מסוימות מפני‬
‫מספרים "לא הגיוניים"‪.‬‬
‫עקב מגבלות אלה‪ ,‬ב‪ Python-‬קיים טיפוס המסוגל לייצג מספר שלם בכל גודל שהוא (!)‪ .‬השימוש במספר שלם ארוך‬
‫זהה לשימוש במספר שלם רגיל‪ ,‬וההבדל היחיד הוא בהצהרה על המספר השלם הגדול‪.‬‬
‫הכוונה ב"כל גודל שהוא" היא ש‪ Python-‬דואגת לשמור משתנה בגודל הדרוש כך שיחזיק את כל המספר‪ ,‬ודואגת‬
‫לשנות את גודל המשתנה בהתאם עם כל שינוי של ערך המספר‪.‬‬
‫‪ L‬אחרי המספר ( ‪ L‬עבור‬ ‫יצירת משתנה ארוך דומה מאוד ליצירת משתנה שלם רגיל‪ .‬ההבדל היחיד הוא הוספת האות‬
‫‪ L‬גדולה – הרבה יותר ברור‬ ‫‪ .)Long‬אין משמעות להוספת ‪ L‬קטנה או גדולה‪ ,‬אבל מומלץ בתור הרגל לכתוב תמיד‬
‫שהכוונה ליצירת מספר ארוך‪ ,‬ולא הספרה אחת (‪.)1‬‬

‫‪>>> 2L‬‬
‫‪2L‬‬

‫‪32-bit‬‬ ‫ברגע זה נוצר משתנה ארוך (המאוחסן ב‪ .)_-‬כאמור‪ ,‬ייצוג משתנה זה בזיכרון שונה מאוד מהייצוג של מספרי‬
‫רגילים‪ .‬עכשיו נחשב את ‪ 2‬בחזקת ‪ ,64‬דבר שאי‪-‬אפשר לעשות עם משתנים רגילים‪:‬‬

‫‪>>> 2L**64‬‬
‫‪18446744073709551616L‬‬

‫וכמובן‪ ,‬אפשר לעשות עוד המון חישובים ארוכים‪ ,‬ולהראות איך ש‪ Python-‬יודע לרשום ממש הרבה מספרים על‬
‫המסך‪...‬‬
‫דבר שחשוב לציין הוא שבדוגמה האחרונה חושב המספר ‪ 2‬בחזקת ‪ .64‬במבוא (פרק קודם) נרשמה דוגמה ובה חושב ‪2‬‬
‫בחזקת ‪ 2‬בחזקת ‪ ...( 2‬ככה ‪ 5‬פעמים)‪ .‬הדוגמה תעבוד על ‪ Python‬בגרסאות של ‪ 2.2‬ומעלה‪ ,‬אבל לא תעבוד על‬
‫גרסאות ‪ 2.0‬ו‪ 2.1 -‬אם לא יירשם ‪ 2L‬במפורש‪ .‬הסיבה היא ש‪ Python -‬בגרסאות הישנות לא מאפשר מעבר אוטומאטי בין‬
‫‪ Python‬בגירסאות ‪2.2‬‬ ‫שלמים רגילים לשלמים ארוכים‪ ,‬ולכן יש לציין במפורש מתי משתמשים בשלמים ארוכים‪ .‬ב‪-‬‬
‫ומעלה יש המרה אוטומאטית למספר שלם ארוך כאשר מתבצעת גלישה‪ .‬לכן‪ ,‬תמיד עדיף להוסיף ‪ L‬אחרי המספר‪ ,‬כדי‬
‫להיות בטוחים שתוכניות ה‪ Python-‬ירוצו כמו שצריך על כל גירסא (כמובן‪ ,‬רק אם יש צורך במספר ארוך)‪.‬‬
‫סוג המשתנה הבא והאחרון לסעיף זה הוא המספר העשרוני‪ .‬ייצוג המספר העשרוני שונה ממספר שלם‪ ,‬ולכן חלות עליו‬
‫מגבלות מסוימות‪ .‬גם למספר עשרוני יש גבולות (הגבולות תלויים במימוש של המספר העשרוני – האם זה מספר‬
‫עשרוני של ‪ 32-bit‬או של ‪ ,)64-bit‬אבל אין לו טיפוס מקביל לשם הארוך‪.‬‬
‫יצירת משתנה עשרוני היא כמו ב‪ ,C -‬ע"י כתיבת מספר עם נקודה עשרונית ושבר (אפשר שבר ‪ ,0‬רק כדי להצהיר שזה‬
‫מספר עשרוני)‪.‬‬

‫‪>>> 21.0‬‬
‫‪21.0‬‬

‫כמו כן‪ ,‬כאשר משלבים בחישוב מסוים מספר עשרוני‪ ,‬התוצאה הופכת אוטומטית להיות עשרונית‪ ,‬אלא אם כן‬
‫משתמשים באחת מפונקציות ה‪( casting -‬אותן נראה בהמשך)‪.‬‬

‫‪>>> 1.0/2‬‬
‫‪0.5‬‬

‫כאשר משלבים בחישוב מספר ארוך ומספר עשרוני יכול להיווצר מקרה בו התוצאה גדולה מדי כדי להיות מיוצגת בצורה‬
‫עשרונית‪ .‬אם ניתן לחשב את התוצאה ולאחסן אותה‪ ,‬לא תהיה שום בעיה‪:‬‬

‫‪>>> 21L/7.0‬‬
‫‪3.0‬‬

‫אבל אם לוקחים מספר ממש ממש ארוך ומבצעים חישוב עם מספר עשרוני‪ ,‬תיווצר שגיאה‪:‬‬

‫‪>>> (2L**2**2**2**2) / 3.0‬‬


‫‪Traceback (most recent call last):‬‬
‫? ‪File “<stdin>”, line 1, in‬‬
‫‪OverflowError: long int too large to convert to float‬‬

‫בסיסים‪ :‬בסיסי ספירה ב‪ Python-‬נכתבים ומתנהגים כמו ב‪:C-‬‬


‫כאשר רוצים לייצג מספר בבסיס ‪ ,Hexadecimal( 16‬או בקיצור ‪ )Hex‬משתמשים בקידומת ‪:0x‬‬

‫‪>>> 0xBEE‬‬
‫‪3054‬‬

‫‪ Python‬כמובן יציג את המספר בייצוג עשרוני‪ ,‬וזוהי דרך מצויינת להמיר מבסיס לבסיס ממש מהר‪ .‬אפשר לעשות גם את‬
‫הפעולה ההפוכה‪ ,‬בעזרת הפונקצייה המובנית )(‪ hex‬שמקבלת מספר ומחזירה מחרוזת המכילה את המספר בייצוג‬
‫הקסהדצימלי‪:‬‬

‫‪>>> 0xBEE‬‬
‫‪3054‬‬
‫)_(‪>>> hex‬‬
‫‟‪„0xbee‬‬

‫ייצוג מספרים בבסיס ‪ )Octal( 8‬נעשה ע"י הוספת אפס לפני המספר אותו רוצים לייצג‪.‬‬

‫‪>>> 045‬‬
‫‪37‬‬

‫כמו הפונקצייה )(‪ ,hex‬קיימת פונקצייה מובנית בשם )(‪ oct‬שממירה מספר דצימלי למחרוזת בייצוג אוקטלי‪:‬‬

‫)‪>>> oct(45‬‬
‫‟‪„055‬‬

‫אופרטורים‪ :‬בתת‪ -‬סעיף זה נראה את כל האופרטורים שיכולים לפעול על מספרים‪ .‬יש לשים לב כי יש אופרטורים‬
‫שפועלים בין מספרים לבין טיפוסים אחרים‪ ,‬אבל כאן נציג רק את האופרטורים הקשורים למספרים‪.‬‬
‫‪ .C‬כלומר‪ ,‬כאשר יש פעולה בין ‪ 2‬אופרנדים זהים‪ ,‬התוצאה היא‬ ‫חיבור (‪ ,)+‬חיסור (‪ )-‬וכפל (*) פועלים כמו בשפת‬
‫מהסוג של האופרנדים‪ .‬כאשר האופרנדים לא זהים‪ ,‬התוצאה תהיה מהטיפוס ה"יותר מתקדם"‪ :‬בכל פעולה בה מעורב‬
‫מספר עשרוני התוצאה תהיה עשרונית‪ .‬אם בפעולה לא מעורב משתנה עשרוני‪ ,‬אבל מעורב משתנה ארוך‪ ,‬התוצאה‬
‫תהיה ארוכה‪.‬‬
‫חילוק (‪ )/‬גם פועל כמו ב‪ ,C -‬וכאשר ישנם טיפוסי נתונים שונים שמעורבים בחישוב‪ ,‬הכלל לגבי חיבור חיסור וכפל קובע‬
‫גם כאן‪ .‬כאשר יש חילוק בין שלמים‪ ,‬התוצאה תמיד שלמה‪ .‬לעומת זאת‪ ,‬אם רוצים תוצאה עשרונית‪ ,‬חייב להיות מעורב‬
‫מספר עשרוני‪.‬‬
‫אם רוצים לאלץ את ‪ Python‬לייצר תוצאה עשרונית‪ ,‬אבל משתמשים רק במשתנים שלמים‪ ,‬ניתן להשתמש בפונקצייה‬
‫)(‪ float‬כדי להמיר את אחד המשתנים השלמים למספר עשרוני‪ ,‬ועל‪-‬ידי כך לגרום לתוצאה להיות עשרונית‪:‬‬

‫‪>>> x = 8‬‬
‫‪>>> y = 3‬‬
‫‪>>> x/y‬‬
‫‪2‬‬
‫‪>>> float(x) / y‬‬
‫‪2.6666666666666665‬‬

‫כמובן‪ ,‬כדי לקבל תוצאה עשרונית נכונה בדוגמה האחרונה‪ ,‬לא ניתן לעשות את הדבר הבא‪:‬‬

‫)‪>>> float(x/y‬‬
‫‪2.0‬‬

‫במקרה כזה קודם ‪ x/y‬מחושב‪ ,‬ורק אז הוא מומר למשתנה עשרוני‪...‬‬


‫מודולו (‪ )%‬לא מתנהג כמו בשפת ‪ ,C‬הוא קצת יותר משוכלל‪ .‬אופרטור המודולו יכול לקבל מספרים שלמים רגילים‪,‬‬
‫ארוכים וגם משתנים עשרוניים‪ .‬התוצאה במקרים בהם המספרים שלמים וארוכים ברורה‪ ,‬היא מחזירה את השארית של‬
‫החלוקה בין שני המספרים‪ ,‬והטיפוס (כמו בכל האופרטורים האחרים) יהיה לפי הכלל של חיבור וחיסור‪.‬‬
‫במקרה בו אחד האופרטורים הוא משתנה עשרוני‪ ,‬התוצאה מחושבת כמספר שלם (כלומר‪ ,‬מחושב המודולו של שני‬
‫הפרמטרים‪ ,‬והתוצאה הנה בצורת מספר עשרוני)‪.‬‬
‫דוגמה להתנהגות זו‪:‬‬

‫‪>>> 3.0 % 6.0‬‬


‫‪3.0‬‬
‫‪>>> 6.0 % 3.0‬‬
‫‪0.0‬‬
‫‪>>> 2.5 % 3.5‬‬
‫‪2.5‬‬

‫‪ 3‬ו‪ ,6 -‬כי הם בסך‪-‬הכל שלמים שמיוצגים בצורה עשרונית‪ .‬בדוגמה‬ ‫בדוגמה הראשונה חושב המודולו של המספרים‬
‫השניה חושב המודולו ההפוך (והתוצאה בהתאם)‪.‬‬
‫בדוגמה השלישית לעומת זאת‪ ,‬חושבה השארית של ‪ 2.5‬לחלק ל‪.3.5-‬‬

‫מחרוזות‬
‫מחרוזות ב‪ Python-‬מיוצגות בצורה הפוכה מ‪ :C -‬ב‪ ,C -‬מחרוזת היא אוסף של תווים‪ .‬ב‪ ,Python -‬מחרוזת היא טיפוס נתונים‬
‫מובנה‪ ,‬ותו הוא מחרוזת באורך ‪ .1‬ייצוג זה מקל מאוד על העבודה עם מחרוזות – מה שמצריך ב‪ C -‬שימוש בפונקציות של‬
‫הספריה >‪ <string.h‬מצריך כאן שורת קוד אחת קצרצרה‪.‬‬
‫בנוסף לכך‪ ,‬קיימת ספריה ב‪ Python-‬שנקראת ‪ ,string‬ובה הרבה פונקציות לטיפול מתקדם במחרוזות‪ ,‬כך שלמעשה‬
‫טיפול במחרוזות הוא קל מאוד‪.‬‬
‫יצירת מחרוזת תיעשה באחת מהצורות הבאות‪:‬‬

‫= ‪>>> str‬‬ ‫”!‪“Look how easy‬‬


‫‪>>> str‬‬
‫‪„Look how‬‬ ‫‟!‪easy‬‬
‫= ‪>>> rts‬‬ ‫‟!‪„Look how easy‬‬
‫‪>>> rts‬‬
‫‪„Look how‬‬ ‫‟!‪easy‬‬

‫כמו שניתן לראות‪ ,‬מחרוזות ניתן ליצור בשתי צורות‪ :‬המחרוזת נמצאת בין ‪ 2‬תווים של גרשיים או בין ‪ 2‬תווים של גרש‬
‫בודד‪ .‬כמובן‪ ,‬אם מחרוזת נמצאת בין ‪ 2‬תווים של גרשיים‪ ,‬ניתן לכלול בה גרש בודד (בלי ‘\’)‪ ,‬ולהפך‪ .‬כמובן‪ ,‬אפשר‬
‫להשתמש בתו ה‪ ’\‘-‬כדי לכלול את התווים האלה במחרוזות‪.‬‬
‫כמו כן‪ ,‬כל הצירופים של ‘\’ ותו אחריהם מ‪ C -‬תקפים ב‪ ’\n‘ :Python-‬לשורה חדשה‪ ’\r‘ ,‬לתחילת השורה‪’\b‘ ,‬‬
‫לחזור תו אחד אחורה‪ ’\t‘ ,‬עבור טאב‪ ,‬וכו'‪...‬‬
‫כמו כן‪ ,‬ב‪ Python-‬יש מנגנון מובנה לפירמוט (‪ )Formatting‬של מחרוזות (מה שעושה )(‪ .)printf‬זה נעשה ע"י כתיבת כל‬
‫ה‪ %-‬המוכרים כבר מ‪ C-‬לתוך המחרוזת וכתיבת כל הפרמטרים אחרי המחרוזת‪:‬‬

‫)‟‪>>> “I am %d years old, and my cat‟s name is %s.” % (17, „Shmulik‬‬


‫”‪“I am 17 years old, and my cat‟s name is Shmulik.‬‬

‫בפועל‪ ,‬אחרי המחרוזת יש את התו ‘‪ ,’%‬ואחריו אנחנו מעבירים ‪( Tuple‬הטיפוס יוצג בהמשך פרק זה) של כל הפרמטרים‪,‬‬
‫לפי הסדר‪ .‬אם מעבירים מספר לא מדויק של פרמטרים (למשל‪ ,‬רשמנו רק ‪ %d‬במחרוזת‪ ,‬והעברנו שני פרמטרים)‪ ,‬יש‬
‫שגיאה‪ .‬כמו כן‪ ,‬אם מעבירים פרמטר שהוא לא מהסוג שהעברנו ב‪( % -‬מחרוזת עבור ‪ ,%d‬וכו')‪ ,‬גם יש שגיאה‪.‬‬
‫פירמוט המחרוזות של ‪ Python‬הרבה יותר מוגן ונוח מזה של ‪ ,C‬הוא לא מצריך קריאה לפונקציה‪ ,‬וניתן להכניס אותו בכל‬
‫מקום‪ ,‬אפילו בתוך קריאה לפונקציה (בפרמטר‪ ,‬במקום להכניס סתם מחרוזת רגילה‪ ,‬מכניסים מחרוזת מפורמטת)‪:‬‬

‫‪>>> def func(s):‬‬


‫‪...‬‬ ‫‪print s*5‬‬
‫‪...‬‬
‫))”‪>>> func(“yanti%s” % (“parazi‬‬
‫‪yantiparaziyantiparaziyantiparaziyantiparaziyantiparazi‬‬

‫כעת נסקור כמה פונקציות שימושיות מאוד‪ .‬חלק מפונקציות אלה מובנות ב‪ Python-‬עצמה‪ ,‬וחלקן של טיפוס המחרוזת‪.‬‬
‫)(‪ chr‬מקבלת כקלט מספר המייצג את ערך ה‪ ASCII -‬של תו מסוים‪ ,‬ומחזירה מחרוזת ובה תו אחד שערך ה‪ ASCII -‬שלו‬
‫הוא הערך שקיבלה הפונקציה כפרמטר‪:‬‬

‫)‪>>> chr(97‬‬
‫‟‪„a‬‬
‫)‪>>> chr(65‬‬
‫‟‪„A‬‬

‫)(‪ str‬לעומתה מקבלת משתנה ומנסה להמיר אותו למחרוזת‪ .‬הפונקציה מסוגלת לקבל יותר מטיפוסים בסיסיים‪ ,‬אפילו‬
‫רשימות ומילונים (נראה בהמשך)‪:‬‬

‫)‪>>> str(1234‬‬
‫‟‪„1234‬‬
‫)]‪>>> str([1,2,3‬‬
‫‟]‪„[1, 2, 3‬‬

‫הפונקציה )(‪ split‬עושה דבר דומה ל‪ split-‬ב‪ ,Perl-‬כאשר היא מקבלת מחרוזת ותו‪ ,‬ומפצלת את המחרוזת לרשימה‪ ,‬כאשר‬
‫התו שהיא קיבלה מפריד בין האיברים ברשימת הפלט‪ .‬לדוגמה‪:‬‬

‫)„ „(‪>>> „look at me‟.split‬‬


‫]‟‪[‟look‟, „at‟, „me‬‬

‫הפונקציה )(‪ ,join‬לעומתה‪ ,‬עושה בדיוק ההפך – היא מקבלת רשימה‪ ,‬ומופעלת על מחרוזת‪ .‬הפלט הוא מחרוזת‬
‫המורכבת מכל איברי הרשימה‪ ,‬והמחרוזת הנתונה ביניהם‪:‬‬

‫)]‟‪>>> „ „.join([‟Hello,‟, „world‟, „I‟, „am‟, „a‟, „joined‟, „string‬‬


‫‟‪„Hello, world I am a joined string‬‬

‫‪ ,Python‬שכמו‬ ‫דבר שלא ניתן לעשות עם מחרוזות הוא לשנות את ערכו של תו בודד‪ .‬הסיבה לכך נעוצה במימוש של‬
‫שכבר ציינו בנוי ממצביעים‪ .‬מחרוזת היא מצביע לעצם שמכיל את המחרוזת‪ .‬הביטוי הבא‪:‬‬

‫‟‪>>> s = „ugifletzet‬‬
‫]‪>>> s[1‬‬
‫‟‪„g‬‬

‫מחזיר תת‪-‬מחרוזת שמכילה רק תו אחד במחרוזת‪ ,‬ולא מאפשר השמה לערך זה‪ .‬אם נרצה לשנות את המחרוזת‪ ,‬ניאלץ‬
‫להזין את המשתנה בערך חדש לגמרי‪.‬‬
‫בסעיף על רשימות נראה שבאמצעות ‪ Slicing‬ניתן לקבל תת‪-‬מחרוזת (ולא רק תו אחד)‪.‬‬

‫מחרוזות ‪Unicode‬‬
‫דבר נוסף שנתמך ע"י ‪ Python‬הוא מחרוזות ‪ – Unicode‬מחרוזות אלו הן מחרוזות בהן כל תו מיוצג ע"י שני בתים‪ ,‬וכך ניתן‬
‫לייצג יותר תווים בטיפוס אחד‪ .‬התמיכה ב‪ Unicode -‬היא לא לשימוש שוטף ב‪ ,Python -‬אלא יותר עבור תאימות עם‬
‫מודולים שיש להם ממשק הדורש ‪.Unicode‬‬
‫מחרוזת ‪ Unicode‬נוצרת בדיוק כמו מחרוזת רגילה‪ ,‬רק שלפני המחרוזת יש את התו ‘‪:’u‬‬

‫‟‪>>> u‟Unicode String‬‬


‫‟‪u‟Unicode String‬‬
‫)_(‪>>> type‬‬
‫>‟‪<type „unicode‬‬

‫רשימות‬
‫רשימה היא טיפוס שמחזיק טיפוסים אחרים‪ ,‬שומר על הסדר שלהם‪ ,‬מאפשר להוסיף‪ ,‬להסיר ולקבל איברים מכל מקום‬
‫ברשימה‪ ,‬וניתן לעבור על כל אחד מהאיברים שברשימה‪ .‬ב‪ ,Python -‬רשימה היא טיפוס מובנה‪ ,‬ובנוסף‪ ,‬רשימה אחת‬
‫יכולה להחזיק איזה טיפוס שנרצה‪ ,‬ואפילו כמה סוגי טיפוסים בבת‪-‬אחת‪.‬‬
‫יצירת רשימה נעשית ע"י רשימה בה איבריה מופיעים בין סוגריים מרובעות‪:‬‬

‫]‪>>> x = [1, 2, 3, 4, 5‬‬


‫‪>>> x‬‬
‫]‪[1, 2, 3, 4, 5‬‬

‫זאת הרשימה שמכילה את המספרים ‪ 1‬עד ‪.5‬‬


‫עכשיו נוסיף לרשימה את האיבר ‪ – 6‬את זה ניתן לעשות ב‪ 2-‬דרכים‪ .‬הראשונה‪ ,‬לחבר שתי רשימות‪:‬‬

‫]‪>>> x = x + [6‬‬
‫‪>>> x‬‬
‫]‪[1, 2, 3, 4, 5, 6‬‬

‫והשניה היא להשתמש בפונקציה )(‪ append‬הפועלת על רשימה‪:‬‬

‫)‪>>> x.append(6‬‬
‫‪>>> x‬‬
‫]‪[1, 2, 3, 4, 5, 6‬‬

‫הדרך הראשונה יכולה לגרום להקצאה של רשימה חדשה – וזה בגלל שיכול להיות שנוצרת רשימה חדשה אליה‬
‫מוכנסים האיברים של שתי הרשימות המחוברות‪ ,‬ובה משתמשים מאותו הרגע‪ .‬הדרך השניה מבטיחה שלא תהיה יצירה‬
‫של רשימה חדשה‪ ,‬אלא שימוש ברשימה הקיימת והוספת איבר אליה‪.‬‬
‫כמו כן‪ ,‬ניתן "לשכפל" רשימה‪ ,‬כלומר להעתיק את אותה הרשימה מספר פעמים‪:‬‬

‫‪>>> x * 3‬‬
‫]‪[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6‬‬
‫‪ – Slicing‬או בעברית "חיתוך"‪ ,‬היא הפעולה בה אנחנו לוקחים רשימה קיימת ויוצרים ממנה רשימה חדשה‪ ,‬ע"י חיתוך של‬
‫חלק מהרשימה המקורית‪ .‬ה‪ Slicing -‬נעשה ע"י ציון האינדקסים של תחילת וסיום החיתוך‪ .‬לדוגמה‪ ,‬הנה רשימה חדשה‬
‫שמורכבת מאינדקסים ‪ 1‬עד (לא כולל!) ‪:3‬‬

‫]‪>>> x[1:3‬‬
‫]‪[2, 3‬‬

‫המספר הראשון (לפני הנקודותיים) הוא האינדקס ממנו מתחיל החיתוך‪ ,‬והמספר השני הוא האינדקס שבו יסתיים‬
‫החיתוך‪ ,‬אבל הוא בעצמו לא ייכלל ברשימה הנוצרת‪.‬‬
‫מטעמי נוחות‪ ,‬כאשר רוצים להעתיק קטע רשימה שמתחיל מיד בהתחלה שלה‪ ,‬או מסתיים מיד בסופה‪ ,‬אין צורך לציין‬
‫את האינדקס הראשון (תמיד ‪ )0‬או את האינדקס האחרון (תמיד אורך הרשימה)‪ ,‬וניתן להשמיט אותו‪ .‬לדוגמה‪ ,‬הנה‬
‫הרשימה עד אינדקס ‪:4‬‬

‫]‪>>> x[:4‬‬
‫]‪[1, 2, 3, 4‬‬

‫והנה הרשימה מאינדקס ‪ 4‬ועד סופה‪:‬‬

‫]‪>>> x[4:‬‬
‫]‪[5, 6‬‬

‫כמו כן‪ ,‬כאשר משמיטים גם את התחלת הרשימה וגם את סופה‪ ,‬מקבלים את כל הרשימה‪:‬‬

‫]‪>>> x[:‬‬
‫]‪[1, 2, 3, 4, 5, 6‬‬

‫לכאורה זהו בזבוז מקום‪ ,‬הרי ניתן לרשום סתם ‪ x‬ולקבל את הרשימה כמו שהיא‪ ,‬אבל מיד נראה למה זה טוב‪.‬‬

‫כמו שכבר ציינו מקודם‪ ,‬ב‪ Python-‬משתנים הם בסך‪-‬הכל מצביעים‪ ,‬כלומר שם של משתנה הוא מצביע לטיפוס מסוים‪.‬‬
‫כאשר משתנה מצביע לטיפוס כלשהו – בין אם זה טיפוס מובנה או טיפוס שנוצר ע"י המשתמש (בהמשך החוברת נראה‬
‫כיצד עושים את זה)‪ ,‬הוא מצביע לכתובת מסוימת בזיכרון‪ .‬כאשר מבצעים השמה (עושים =) בין שני משתנים‪,‬‬
‫מעתיקה את המצביע ממשתנה אחד למשתנה‬ ‫והמשתנים הם לא מטיפוס "פשוט" (לא מספר)‪ ,‬ההשמה למעשה‬
‫האחר‪.‬‬
‫בדוגמה הבאה ניצור רשימה בשם ‪ ,x‬נשים אותה במשתנה ‪ ,y‬נוסיף איבר לרשימה ‪ y‬ונראה כיצד הרשימה ‪ x‬משתנה גם‬
‫כן‪:‬‬

‫>>>‬ ‫]‪x = [1, 2, 3‬‬


‫>>>‬ ‫‪y = x‬‬
‫>>>‬ ‫)‪y.append(4‬‬
‫>>>‬ ‫‪x‬‬
‫‪[1,‬‬ ‫]‪2, 3, 4‬‬
‫>>>‬ ‫‪y‬‬
‫‪[1,‬‬ ‫]‪2, 3, 4‬‬

‫הדוגמה האחרונה מראה תכונה חזקה מאוד של ‪ – Python‬אין בה צורך במצביעים‪ ,‬כיוון שאין מה משהו אחר ממצביעים‪.‬‬
‫ב‪ Python-‬כל משתנה הוא מצביע‪ ,‬והשמה היא העתקה של המצביע‪ ,‬ולא התוכן (למעט מספרים ומחרוזות)‪.‬‬
‫כאשר מעבירים פרמטרים לפונקציה‪ ,‬הדבר עובד באותה הצורה – שינוי של פרמטר שיועבר לפונקציה הוא שינוי‬
‫המשתנה המקורי שהועבר לפונקציה‪.‬‬

‫תכונה זו מאוד נוחה‪ ,‬אבל לפעמים נרצה ליצור עותק של משתנה קיים – מה נעשה אז? השיטה הכי טובה היא‬
‫להשתמש ב‪ Slicing-‬אותו למדנו מקודם‪ ,‬ובו ראינו שכאשר עושים ‪ Slicing‬שכולל את כל האיברים (בלי ציון התחלה ובלי‬
‫ציון סוף)‪ ,‬נוצר עותק חדש של העצם המקורי‪ .‬כעת נראה איך תתבצע ההשמה עם ‪:Slicing‬‬

‫>>>‬ ‫]‪x = [1, 2, 3‬‬


‫>>>‬ ‫]‪y = x[:‬‬
‫>>>‬ ‫)‪y.append(4‬‬
‫>>>‬ ‫‪x‬‬
‫‪[1,‬‬ ‫]‪2, 3‬‬
‫>>>‬ ‫‪y‬‬
‫‪[1,‬‬ ‫]‪2, 3, 4‬‬

‫יש לציין שה‪ Slicing-‬יעבוד עבור מחרוזות‪ ,‬רשימות‪-Tuple ,‬ים‪ ,‬וכל טיפוס סדרתי‪.‬‬

‫‪Tuples‬‬
‫‪ Tuple‬הוא טיפוס של רשימה קבועה‪ .‬הטיפוס נועד לשימוש במצבים בהם אין אפשרות ליצור רשימה‪ ,‬או כאשר יש צורך‬
‫ברשימה שאורכה לא משתנה‪ .‬כמו כן‪ ,‬לא ניתן לשנות אף אחד מהאיברים ב‪.Tuple -‬‬

‫יצירת ‪ Tuple‬נעשית בדיוק כמו יצירת רשימה‪ ,‬רק שבמקום סוגריים מרובעות משתמשים בסוגריים עגולות‪:‬‬
‫)‪>>> t = (1, 2, 3‬‬
‫‪>>> t‬‬
‫)‪(1, 2, 3‬‬

‫קבלת איבר מה‪ Tuple-‬היא כמו איבר מרשימה – ע"י סוגריים מרובעות‪:‬‬

‫]‪>>> t[0‬‬
‫‪1‬‬

‫אבל אם ננסה לשנות איבר ברשימה‪ ,‬לא יהיה ניתן לעשות זאת‪:‬‬

‫‪>>> t[0] = 2‬‬


‫‪Traceback (most recent call last):‬‬
‫? ‪File "<stdin>", line 1, in‬‬
‫‪TypeError: object doesn't support item assignment‬‬

‫כמו כן‪ ,‬ניתן לחבר שני ‪-Tuple‬ים‪ .‬התוצאה תהיה ‪ Tuple‬חדש‪:‬‬

‫>>>‬ ‫‪t1‬‬ ‫)‪= (1, 2, 3‬‬


‫>>>‬ ‫‪t2‬‬ ‫)‪= (4, 5, 6‬‬
‫>>>‬ ‫‪t1‬‬ ‫‪+ t2‬‬
‫‪(1,‬‬ ‫‪2,‬‬ ‫)‪3, 4, 5, 6‬‬

‫צריך לדעת שלא ניתן לחבר ‪ Tuple‬לרשימה‪ ,‬משום שהם אינם טיפוסים מאותו הסוג‪.‬‬
‫בנוסף לחיבור‪ ,‬ניתן לעשות ‪ Slicing‬על ‪:Tuple‬‬

‫)‪>>> t = (1, 2, 3, 4, 5‬‬


‫]‪>>> t[1:4‬‬
‫)‪(2, 3, 4‬‬

‫ובדומה לרשימה‪ ,‬השמת ‪ Tuple‬לא תיצור עותק שלו אלא תעביר מצביע‪ .‬ליצירת עותק יש להשתמש ב‪.Slicing-‬‬

‫‪ – Tuple Assignments‬כאשר מבצעים השמה בין שני ‪-Tuple‬ים‪ Python ,‬מבצעת השמה בין כל שני איברים מתאימים ב‪-‬‬
‫‪-Tuple‬ים‪ .‬לדוגמה‪:‬‬

‫>>>‬ ‫)‪(a, b, c) = (1, 2, 3‬‬


‫>>>‬ ‫‪a‬‬
‫‪1‬‬
‫>>>‬ ‫‪b‬‬
‫‪2‬‬
‫>>>‬ ‫‪c‬‬
‫‪3‬‬

‫בדוגמה האחרונה נוצרו שני ‪-Tuple‬ים – באחד שלושה משתנים‪ ,‬ובשני שלושה ערכים‪ Python .‬עשתה השמה בין ‪ a‬ל‪,1-‬‬
‫בין ‪ b‬ל‪ 2 -‬ובין ‪ c‬ל‪ .3 -‬בצורה כזו‪ ,‬נוצרו שלושה משתנים עם שלושה ערכים התחלתיים בשורה אחת‪ .‬כמובן‪ ,‬לא ניתן‬
‫לבצע השמה בין שני ‪-Tuple‬ים שמכילים "סתם" איברים שלא ניתן להשם ביניהם‪:‬‬

‫)‪>>> (1, 2, 3) = (1, 2, 3‬‬


‫‪SyntaxError: can't assign to literal‬‬

‫אחד הטריקים שניתן לבצע בעזרת ‪ Tuple Assignments‬הוא החלפת ערכי שני משתנים בשורה אחת‪:‬‬

‫‪>>> x, y = y, x‬‬

‫השורה האחרונה פשוט החליפה בין הערכים של ‪ x‬ו‪ ,y-‬ללא צורך במשתנה זמני‪.‬‬

‫השימוש העיקרי ב‪-Tuple-‬ים ב‪ Python-‬הוא עבור אחסון מידע שאין צורך לשנותו (או שיש צורך לוודא שהוא לא ישתנה)‪.‬‬
‫‪ Tuple‬הוא טיפוס‪ ,‬ניתן להחזיר‬ ‫כמו כן‪ ,‬בהמשך החוברת נראה שפונקציה יכולה להחזיר רק איבר אחד‪ .‬משום ש‪-‬‬
‫מפונקציה ‪ Tuple‬המכיל מספר איברים‪ ,‬וע"י כך להחזיר יותר מאיבר אחד מפונקציה‪.‬‬

‫מילונים‬
‫מילון ( ‪ )Dictionary‬ב‪ Python -‬הוא טיפוס שמטרתו היא המרה בין מפתחות לבין ערכים (ב‪ C++ -‬קיימת המחלקה ‪map‬‬
‫לכך)‪ .‬מילון למעשה מחזיק ערכים‪ ,‬מפתחות ואת המיפוי ביניהם‪ .‬כאשר המשתמש פונה למילון‪ ,‬הוא מציין מפתח‪,‬‬
‫ומקבל עבורו ערך‪ .‬היתרון בכך הוא שבמקום מספרי אינדקסים (שלא ממש אומרים משהו למישהו)‪ ,‬ניתן להשתמש‬
‫בכל ערך שרק רוצים‪ ,‬אפילו מחרוזות‪.‬‬

‫יצירת מילון נעשית כמו רשימה‪ ,‬אבל עם סוגריים מסולסלות‪:‬‬


‫}{ = ‪>>> d‬‬

‫כעת נוסיף למילון ‪ d‬את המיפוי בין המפתח ‪ 1‬למחרוזת “‪:”Sunday‬‬

‫”‪>>> d[1] = “Sunday‬‬


‫‪>>> d‬‬
‫}'‪{1: 'Sunday‬‬

‫כעת המילון ‪ d‬יודע שה"ערך" של ‪ 1‬הוא "‪ ."Sunday‬בקשת ערך עבור מפתח מסוים נעשית כמו ברשימה‪:‬‬

‫]‪>>> d[1‬‬
‫'‪'Sunday‬‬

‫כמו כן‪ ,‬ניתן ליצור מפתחות שאינם מספרים‪ .‬למשל‪ ,‬ניצור מילון שממיר בין מדינה לבירה שלה‪:‬‬

‫>>>‬ ‫}{ = ‪cap‬‬


‫>>>‬ ‫'‪cap['Israel'] = 'Jerusalem‬‬
‫>>>‬ ‫'‪cap['USA'] = 'Washington‬‬
‫>>>‬ ‫'‪cap['Russia'] = 'Moscow‬‬
‫>>>‬ ‫'‪cap['France'] = 'Paris‬‬
‫>>>‬ ‫'‪cap['England'] = 'London‬‬
‫>>>‬ ‫'‪cap['Italy'] = 'Rome‬‬

‫בעת פנייה למילון נוכל לציין מייד את שם המדינה ולקבל את הבירה שלה‪:‬‬

‫]'‪>>> cap['France‬‬
‫'‪'Paris‬‬

‫אם נפנה למפתח שאינו קיים‪ ,‬תוחזר שגיאה‪:‬‬

‫]'‪>>> cap['Japan‬‬
‫‪Traceback (most recent call last):‬‬
‫? ‪File "<stdin>", line 1, in‬‬
‫‪KeyError: Japan‬‬

‫בנוסף לפעולות ההמרה‪ ,‬יש מספר פעולות במילון בהן רצוי להשתמש בעת העבודה עם מילון‪:‬‬
‫‪ has_key‬היא פונקציה שמחזירה ‪ 1‬אם המפתח קיים במילון‪ ,‬או ‪ 0‬אם לא‪ .‬לדוגמה‪ ,‬המדינה " ‪ "Japan‬לא קיימת במילון‪:‬‬

‫)'‪>>> cap.has_key('Japan‬‬
‫‪0‬‬

‫‪ keys‬היא פונקציה שמחזירה את רשימת המפתחות במילון‪:‬‬

‫)(‪>>> cap.keys‬‬
‫]'‪['Israel', 'Italy', 'USA', 'England', 'Russia', 'France‬‬

‫‪ values‬היא פונקציה שמחזירה את רשימת הערכים במילון‪:‬‬

‫)(‪>>> cap.values‬‬
‫]'‪['Jerusalem', 'Rome', 'Washington', 'London', 'Moscow', 'Paris‬‬
‫פרק ‪_:4‬בקרת זרימה‬
‫‪if‬‬
‫‪ C‬מלבד‬ ‫‪ if‬היא כמובן פקודת ההתניה ( ‪ ,)Conditioning‬כמו ברוב שפות התכנות‪ .‬מבנה הפקודה דומה לזה שבשפת‬
‫העובדה שאין חובה בסוגריים‪ .‬דוגמה די פשוטה ל‪:if-‬‬

‫‪num = 5‬‬
‫‪if num > 3:‬‬
‫‪print num * 2‬‬

‫בשורה הראשונה יצרנו משתנה בשם ‪ num‬שערכו ‪ .5‬השורה השניה היא שורת ה‪ if -‬עצמה‪ ,‬ומבנה ההתניה דומה לזה‬
‫שב‪( C-‬מיד נראה מספר הבדלים)‪ .‬בסוף השורה השניה יש נקודותים‪ .‬תו ה‪ ':'-‬ב‪ Python-‬מורה על פתיחת בלוק חדש‪,‬‬
‫בדיוק כמו הסוגריים‪-‬המסולסלות ב‪.C-‬‬
‫ואיך ‪ Python‬יודעת מתי בלוק נגמר? את זה היא עושה באמצעות תו ה‪ .TAB -‬בדוגמה למעלה‪ ,‬השורה השלישית מוזחת‬
‫ימינה ב‪ TAB -‬אחד‪ ,‬ולא סתם בשביל אינדנטציה (כמו ב‪ .)C -‬האינדנטציה ( ‪ ,Indentation‬הפעולה בה בלוק שתלוי בבלוק‬
‫קודם ייכתב "פנימה" יותר בקוד‪ ,‬במקרה הזה ימינה ב‪ TAB -‬אחד) ב‪ Python-‬היא חלק מהמבנה שלה‪ ,‬ולכן אי‪-‬אפשר‬
‫לכתוב בלי להוסיף ‪ TAB‬לפני כל שורה בבלוק‪.‬‬

‫דבר נוסף‪ ,‬חשוב לשים את תו ה‪ ,)’\t ‘( TAB -‬ולא שום אלתור אחר‪ ,‬כמו ‪ 4‬או ‪ 5‬רווחים‪ Python .‬מחפש את תו ה‪,TAB -‬‬
‫וצריך להיזהר מלשכוח לשים אותו – אפשר לשבת שעות מול שגיאה שנראית לכאורה בקוד ולגלות בסוף ששכחת‬
‫‪ TAB‬למספר רווחים‪ ,‬או עושים דברים יותר משונים‪ .‬לכן עדיף‬ ‫לשים ‪ .TAB‬כמו כן‪ ,‬ישנם עורכי טקסט שממירים‬
‫‪ .)vi ,EditPlus ,Notepad‬יש לציין שכותבי ה‬ ‫להשתמש בעורכים שאפשר לסמוך עליהם שלא יתעללו בקוד (כמו‬
‫‪ Interpreter‬בנו אותו בצורה יחסית אמינה‪ ,‬שמסוגלת להתמודד גם עם רווחים בחלק מהמקרים‪ .‬בכל אופן ‪ -‬כדאי לא‬
‫לבדוק את היכולת הזו וללכת על בטוח‪.‬‬
‫‪ or ,and‬ו‪ ,not -‬בנוסף‬ ‫בנוסף לתנאים רגילים‪ ,‬אפשר כמובן ליצור תנאים לוגיים‪ .‬ב‪ Python-‬קיימות מילות המפתח‬
‫לאופרטורים הלוגיים שלקוחים מ‪ .C-‬השימוש הוא די פשוט‪:‬‬

‫‪num = 17‬‬
‫‪if (num > 5) or (num == 15):‬‬
‫”‪print “something‬‬

‫השימוש הוא זהה עבור ‪ not .and‬יכול לבוא לפני תנאי כדי להפוך אותו‪:‬‬

‫‪if not 4 == 7:‬‬


‫”‪print “always true‬‬

‫‪while‬‬
‫‪.if‬‬ ‫פקודת הלולאה ‪ while‬מאפשרת חזרה על פקודות על עוד תנאי מסוים מתקיים‪ .‬התנאי יכול להיכתב כמו תנאי ב‪-‬‬
‫דוגמה‪:‬‬

‫‪i = 0‬‬
‫‪while i < 10:‬‬
‫‪print i‬‬
‫‪i += 1‬‬

‫בפקודת ‪ while‬ב‪ Python -‬קיים גם משפט ‪ .else‬משפט זה מתבצע במקרה ובו התנאי שניתן לביצוע הלולאה לא התקיים‬
‫אפילו פעם אחת‪ ,‬ולא הייתה שום כניסה לגוף הלולאה‪:‬‬

‫‪>>> i = 40‬‬
‫‪>>> while i > 50:‬‬
‫‪...‬‬ ‫‪i -= 1‬‬
‫‪...‬‬ ‫‪print i‬‬
‫‪... else:‬‬
‫‪...‬‬ ‫'!‪print 'i is smaller than 50‬‬
‫‪...‬‬
‫!‪i is smaller than 50‬‬

‫‪for‬‬
‫לפני שנסקור את פקודת ‪ ,for‬נגדיר מהו רצף – רצף הוא עצם שמכיל בתוכו איברים‪ ,‬בסדר מסוים‪ ,‬כאשר העצם מכיל‬
‫פונקציות לקבלת כל‪-‬אחד מהאיברים (או פונקציות לקבלת איבר ראשון ואיבר עוקב לאיבר קיים)‪.‬‬

‫פקודת הלולאה ‪ for‬שונה מזו שב‪ for .C-‬ב‪ Python-‬לא מבצעת לולאה על תחום ערכים (כמו ב‪ )Pascal -‬או מאחדת בתוכה‬
‫משפט‪-‬אתחול‪ ,‬תנאי ופקודה לביצוע בכל איטרציה (כמו ב‪.)C-‬‬
‫‪ for‬ב‪ Python -‬מקבלת רצף (כלומר אוסף של איברים)‪ ,‬ובכל איטרציה מתייחסת רק לאיבר אחד ברצף‪ .‬ההתייחסות‬
‫לאיברים נעשית לפי הסדר בו הם מאוחסנים ברצף‪ ,‬כאשר הסדר נקבע לפי טיפוס הנתונים הנתון (אף אחד לא מבטיח‬
‫סדר מסוים‪ ,‬אלא אם כן זוהי אחת מהגדרותיו של טיפוס הנתונים)‪.‬‬

‫דוגמה פשוטה ל‪:for-‬‬

‫)‟‪days = („Sun‟, „Mon‟, „Tue‟, „Wed‟, „Thu‟, „Fri‟, „Sat‬‬


‫‪for day in days:‬‬
‫‪print day‬‬

‫בדוגמה‪ ,‬הלולאה יצרה משתנה בשם ‪ .day‬בכל איטרציה‪ day ,‬מקבל את האיבר הבא של ‪ .days‬הפלט של הריצה יהיה‪:‬‬

‫‪Sun‬‬
‫‪Mon‬‬
‫‪Tue‬‬
‫‪Wed‬‬
‫‪Thu‬‬
‫‪Fri‬‬
‫‪Sat‬‬

‫‪ day‬ימשיך להתקיים‪ ,‬וערכו יהיה הערך האחרון שקיבל במהלך ריצת‬‫חשוב לציין שבסיום ריצת הלולאה‪ ,‬המשתנה‬
‫הלולאה‪.‬‬
‫אם מריצים לולאת ‪ for‬עם רשימה ריקה‪ ,‬כלום לא יקרה והמשתנה ‪( day‬או כל משתנה אחר שייכתב שם) לא ייווצר‪ .‬יש‬
‫לשים לב שאם מריצים כמה לולאות‪ ,‬אחת אחרי השניה‪ ,‬עם אותו משתנה (נגיד ‪ ,)i‬ובאחת הלולאות יש רשימה ריקה‪,‬‬
‫אין הדבר אומר שהמשתנה ‪ i‬יושמד‪ .‬זה רק אומר שהוא לא ישתנה עקב הלולאה הזו‪ .‬אם הלולאה הזו היא הלולאה‬
‫הראשונה‪ i ,‬באמת לא ייווצר‪:‬‬

‫>>>‬ ‫‪for i in xrange(5):‬‬


‫‪...‬‬ ‫‪print i‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫>>>‬ ‫‪i‬‬
‫‪4‬‬
‫>>>‬ ‫‪for i in xrange(0):‬‬
‫‪...‬‬ ‫‪print i‬‬
‫>>>‬ ‫‪i‬‬
‫‪4‬‬

‫כאמור‪ ,‬ניתן לעבור לא רק על רשימות‪ ,‬אלא גם על מילונים ומחרוזות‪ .‬להלן שתי דוגמאות להמחשת העבודה עם‬
‫מחרוזות ומילונים‪:‬‬

‫>>>‬ ‫}{ = ‪dic‬‬


‫>>>‬ ‫‪dic[1] = 10‬‬
‫>>>‬ ‫‪dic[2] = 20‬‬
‫>>>‬ ‫‪dic[3] = 30‬‬
‫>>>‬ ‫‪dic[4] = 40‬‬
‫>>>‬ ‫‪dic[5] = 50‬‬
‫>>>‬ ‫‪for i in dic:‬‬
‫‪...‬‬ ‫‪print i‬‬
‫‪...‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫>>>‬ ‫'‪str = 'Yet another string‬‬
‫>>>‬ ‫‪for char in str:‬‬
‫‪...‬‬ ‫‪print char‬‬
‫‪...‬‬
‫‪Y‬‬
‫‪e‬‬
‫‪t‬‬

‫‪a‬‬
‫‪n‬‬
‫‪o‬‬
‫‪t‬‬
‫‪h‬‬
‫‪e‬‬
‫‪r‬‬

‫‪s‬‬
‫‪t‬‬
‫‪r‬‬
‫‪i‬‬
‫‪n‬‬
‫‪g‬‬

‫הערה לגבי מילונים – בהגדרת המילון לא נאמר שהסדר בו האיברים מופיעים בו הוא הסדר בו הם יאוחסנו או הסדר בו‬
‫הם יוחזרו בלולאת ‪ .for‬לכן‪ ,‬אין להניח הנחות על סדר האיברים בטיפוס מסוים‪ ,‬אלא אם נאמר אחרת בהדגרת הטיפוס‪.‬‬
‫‪ for‬על רשימה מסוימת‪ ,‬והרשימה לא‬ ‫הנחה שכן ניתן להניח (וגם זאת בזהירות רבה מאוד) היא שאם הרצנו לולאת‬
‫השתנתה‪ ,‬ריצת ‪ for‬נוספת על אותה הרשימה תתבצע באותו הסדר‪.‬‬

‫‪range, xrange‬‬
‫טוב‪ ,‬אז יש לולאת ‪ for‬שיודעת לעבור על כל האיברים ברשימה‪ .‬אבל מה אם כן רוצים לעשות לולאת ‪ for‬כמו ב‪ ,C-‬אבל‬
‫לא רוצים להשתמש ב‪.while-‬‬
‫פתרון אחד (לא מומלץ) הוא ליצור רשימה שמכילה את כל המספרים שנרצה לעבור עליהם‪ ,‬מ‪ 0 -‬עד ‪ .X‬ברור שפתרון‬
‫זה לא טוב‪ ,‬אם ‪ X‬משתנה מריצה לריצה‪ ,‬או אם הוא מאוד גדול‪.‬‬
‫‪ range‬ו‪ .xrange -‬שתי הפונקציות עושות את אותו‬ ‫‪ Python‬פותרת עבורנו את הבעיה באמצעות הפונקציות המובנות‬
‫הדבר‪ ,‬אבל בצורה שונה‪ range .‬יוצרת רשימה חדשה אם ערך התחלתי‪ ,‬ערך סופי וקפיצה ( ‪ ,Step‬ההפרש בין כ"א‬
‫מהאיברים)‪.‬‬
‫מבנה הפונקציה ‪:range‬‬

‫)]‪range([start], end, [step‬‬

‫‪ – start‬זהו פרמטר אופציונלי‪ ,‬ומציין את ערך ההתחלה (כולל) של הרשימה‪.‬‬


‫‪ – end‬ערך זה תמיד ייכלל ב‪ range -‬ומציין את הערך האחרון ברשימה (לא כולל)‪ .‬כלומר‪ ,‬הרשימה מגיעה עד הערך‬
‫הזה‪ ,‬ולא כוללת אותו‪.‬‬
‫‪ – step‬ההפרש בין כל שני איברים סמוכים ברשימה‪ .‬כמובן‪ ,‬הפרש זה חייב להיות גדול מאפס‪.‬‬
‫דוגמאות ל‪:range-‬‬

‫‪>>> for i in‬‬ ‫‪range(10):‬‬


‫‪...‬‬ ‫‪print‬‬ ‫‪i‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪8‬‬
‫‪9‬‬
‫‪>>> for i in‬‬ ‫‪range(2, 10, 2):‬‬
‫‪...‬‬ ‫‪print‬‬ ‫‪i‬‬
‫‪2‬‬
‫‪4‬‬
‫‪6‬‬
‫‪8‬‬

‫כלומר‪ range ,‬יוצרת רשימה חדשה עבורנו‪ .‬הרשימה יכולה למעשה להכיל כל סדרה חשבונית שהיא‪.‬‬
‫כמו כן‪ ,‬ניתן לקחת את הרשימה שנוצרה ולהצביע אליה עם משתנה‪ ,‬ואז נקבל רשימה חדשה בממש מעט קוד‪:‬‬

‫)‪k = range(1024‬‬

‫אז בשביל מה יש ‪?xrange‬‬


‫‪ xrange‬לא יוצרת עבורנו רשימה‪ ,‬אלא יוצרת אובייקט רצף‪ ,‬שניתן לקבל ממנו התחלה‪ ,‬סוף ואת האיבר הבא לאיבר‬
‫קיים‪ .‬בצורה כזו‪ ,‬אובייקט ‪ xrange‬מחזיק את תחום הערכים אותו הוא צריך להחזיר ואת ההפרש בין כל שני איברים‪ .‬בכל‬
‫קריאה לקבלת האיבר הבא‪ ,‬האובייקט מחשב את האיבר הבא במקום לאחסן אותו בזיכרון‪ .‬כאשר מבקשים את האיבר‬
‫הבא לאיבר האחרון‪ ,‬אובייקט ה‪ xrange-‬מודיע על סוף הרשימה‪.‬‬
‫הסיבה שנרצה בכלל להשתמש ב‪ xrange -‬היא שעצם יצירת רשימה חדשה‪ ,‬רק עבור הלולאה‪ ,‬ולא כדי להשתמש בה‬
‫מאוחר יותר‪ ,‬היא שיצירת רשימה לוקחת זיכרון‪ ,‬ואם נשתמש ב‪ range-‬עם תחום ערכים גדול‪ ,‬סתם נבזבז זיכרון‪.‬‬
‫לעומת זאת‪ ,‬מבחינת ביצועים‪ range ,‬יותר יעילה מ‪ ,xrange -‬משום שבעת קבלת האיברים מהרשימה‪ xrange ,‬צריכה‬
‫לחשב את האיבר הבא בכל פעם‪ ,‬בעוד ‪ range‬מחזירה רשימה מוכנה לשימוש‪ ,‬וצריך רק להחזיר ממנה את האיבר הבא‬
‫(ואין צורך לחשב אותו)‪ .‬השימוש בכל‪-‬אחת מהפונקציות תלוי במקרה בו משתמשים בהן‪ ,‬והאם יש עדיפות לחיסכון‬
‫בזיכרון או לשיפור בביצועים‪.‬‬
‫המבנה של ‪ xrange‬זהה לזה של ‪.range‬‬

‫‪break, continue‬‬
‫משפט ‪ break‬נועד ליציאה מלולאות ‪ for‬או ‪ break .while‬יוצא רק מבלוק ה‪ for-‬או בלוק ה‪ while-‬בו הוא נמצא‪ ,‬ולא מסוגל‬
‫לצאת החוצה יותר מבלוק אחד‪.‬‬
‫משפט ‪ continue‬מורה להפסיק מיד את האיטרציה הנוכחית של הלולאה ולהתחיל את האיטרציה הבאה‪ .‬כמו ‪ ,break‬גם‬
‫‪ continue‬יכול לצאת רק מבלוק הלולאה הקרוב אליו‪.‬‬
‫דוגמאות‪:‬‬

‫‪>>> for monty in xrange(5):‬‬


‫‪...‬‬ ‫‪for python in xrange(5):‬‬
‫‪...‬‬ ‫‪continue‬‬
‫‪...‬‬ ‫‪print monty * python‬‬
‫‪0‬‬
‫‪4‬‬
‫‪8‬‬
‫‪12‬‬
‫‪16‬‬
‫‪pass‬‬
‫משפט אחרון חביב לפרק זה הוא ‪ – pass‬המשפט שאומר לא לעשות כלום (כן‪ ,‬יש כזה דבר)‪.‬‬
‫הסיבה לכך שיש כזה משפט בכלל היא לא בשביל שאפשר יהיה לכתוב את המשפט הזה בכל מני מקומות בקוד כדי‬
‫שיהיו יותר שורות (בכלל‪ ,‬אי אפשר לרשום אותו בכל מקום)‪.‬‬
‫משפט זה משמש כחלק מבקרת הזרימה‪ :‬לפעמים אנחנו רושמים לולאה‪ ,‬כי אנחנו יודעים שהיא צריכה להיות במקום‬
‫מסוים בקוד‪ ,‬אבל אנחנו לא ממש רוצים לכתוב אותה כרגע‪ ,‬אין לנו איך‪ ,‬או ‪ )9( 1001‬סיבות אחרות‪.‬‬
‫בגלל ש‪ Python-‬מחפשת את תו ה‪ TAB -‬בבלוק חדש‪ ,‬זאת תהיה שגיאה לא לפתוח בלוק במקומות מסוימים‪ .‬כמו כן‪,‬‬
‫זאת שגיאה לשים סתם שורה ריקה עם ‪ TAB‬בהתחלה‪.‬‬
‫לכן‪ ,‬ניתן לרשום במקום הבלוק החסר את המשפט ‪ ,pass‬ו‪ Python-‬פשוט תעבור הלאה את הלולאה‪:‬‬

‫‪>>> for k in xrange(0, 500, 5):‬‬


‫‪...‬‬ ‫‪pass‬‬
‫פרק ‪_:5‬קלט ופלט‬
‫הדפסה למסך‬
‫הדפסה למסך נעשית באמצעות הפקודה המובנית ‪:print‬‬

‫‟‪>>> print „Hello‬‬


‫‪Hello‬‬

‫הפקודה יכולה לקבל פרמטר אחד (כמו בדוגמה האחרונה) או מספר פרמטרים מופרדים בפסיקים‪:‬‬

‫‪>>> print „Hello World!‟, „My age is‟, 17‬‬


‫‪Hello World! My age is 17‬‬

‫כפי שניתן לראות‪ print ,‬מוסיפה אוטומטית רווחים בין הפרמטרים שנשלחים להדפסה‪ .‬כמו כן‪ ,‬ניתן לתת כפרמטר כל‬
‫סוג משתנה‪ ,‬כל עוד ניתן להמיר אותו למחרוזת כדי להדפיס אותו‪.‬‬

‫בנוסף‪ ,‬הפקודה תמיד מדפיסה תו סיום שורה בסופה‪ ,‬אלא אם כן שמים פסיק בסוף השורה‪:‬‬

‫‪>>> for i in range(1):‬‬


‫‪...‬‬ ‫‪print 'look!',‬‬
‫‪...‬‬ ‫'!‪print 'this is the same line‬‬
‫‪...‬‬
‫!‪look! this is the same line‬‬

‫השימוש בלולאת ‪ for‬בדוגמה האחרונה היה כדי ששתי הפקודות יבוצעו אחת אחרי השניה‪ ,‬כי אם נכתוב את הפקודות‬
‫אחרת אחרי השניה ב‪ ,Interpreter -‬ה‪ Interpreter -‬יירד שורה באופן אוטומאטי לאחר כל ביצוע פקודה‪ ,‬כדי לחזור לסמן‬
‫של הכנסת הפקודה הבאה (>>>)‪.‬‬

‫כמו כן‪ ,‬ניתן לתת ל‪ print-‬מחרוזת מפורמטת‪:‬‬

‫‪>>> print „His age is %d.‟ % 17‬‬


‫‪His age is 17.‬‬

‫קלט מהמקלדת‬
‫‪.raw_input‬‬ ‫כאשר תוכנית מעוניינת לקבל קלט מהמשתמש (דרך המקלדת בד"כ)‪ ,‬ניתן להשתמש בפונקציה המובנית‬
‫הפונקציה מקבלת כפרמטר מחרוזת אותה היא מדפיסה למסך‪ ,‬ואז היא ממתינה לשורת קלט מהמשתמש‪ .‬הקלט‬
‫יסתיים כאשר המשתמש יקיש על ‪ .Enter‬דוגמה לשימוש ב‪:raw_input-‬‬

‫)‟ >‪>>> raw_input(„--‬‬


‫!‪--> hello world‬‬
‫‟!‪„hello world‬‬

‫ערך ההחזרה של הפונקציה הוא מחרוזת‪.‬‬

‫קבצים‬
‫הטיפול בקבצים ב‪ Python -‬פשוט בהרבה מזה שב‪ .C -‬פונקציות הטיפול בקבצים מובנות‪ ,‬ונקראות ‪ open‬ו‪ .close -‬פתיחת‬
‫קובץ נעשית באופן הבא‪:‬‬

‫)‟‪>>> file = open(„x.dat‟, „w‬‬

‫כלומר‪ ,‬הפונקציה ‪ open‬מחזירה ‪ Handle‬לקובץ‪ ,‬כאשר הפרמטרים לפונקציה הם שם הקובץ וסוג הגישה (‘ ‪ ’w‬לכתיבה‪’r‘ ,‬‬
‫לקריאה‪ ,‬וכו' כמו ב‪ .)C-‬לאחר מכן ניתן לכתוב לקובץ באמצעות הפונקציה ‪:write‬‬

‫)‟‪<>> file.write(„my first file!\n‬‬


‫)‟!‪>>> file.write(„my second line‬‬

‫בסיום העבודה עם הקובץ יש לסגור אותו באמצעות הפונקציה ‪:close‬‬

‫)(‪>>> file.close‬‬
‫ניתן גם לפתוח קובץ לקריאה ולקרוא ממנו את כל התוכן שלו למשתנה אחד‪:‬‬

‫)‟‪>>> file = open(„x.dat‟, „r‬‬


‫)(‪>>> content = file.read‬‬
‫)(‪>>> file.close‬‬

‫כעת המשתנה ‪ content‬מכיל את תוכן הקובץ שיצרנו בדוגמה הקודמת‪:‬‬

‫‪>>> print content‬‬


‫!‪my first file‬‬
‫!‪my second line‬‬
‫פרק ‪_:6‬פונקציות‬
‫עד כה עסקנו במשחקים קטנים ונחמדים עם קוד קצר ופשוט‪ .‬אבל‪ ,‬כמו שנאמר במבוא‪ Python ,‬היא שפה מאוד חזקה‪,‬‬
‫עד כדי כך שניתן לכתוב בה אפליקציות שלמות‪.‬‬
‫כמובן‪ ,‬כמו בכל שפה‪ ,‬כתיבת אפליקציות (או סתם תוכניות רגילות) תתבצע ע"י חלוקה לפונקציות‪ ,‬פרוצדורות‪,‬‬
‫מודולים‪ ,‬יחידות ספריה‪ ,‬וכו'‪ .‬פרק זה עוסק בפונקציות‪.‬‬

‫הגדרת פונקציות‬
‫בדומה ל‪ ,C -‬אין הבדל בין פונקציות ( ‪ )Functions‬לבין פרוצדורות ( ‪ – )Procedures‬יש פונקציות שמחזירות ערך ויש‬
‫פונקציות שלא‪ .‬בשונה מ‪ ,C -‬פונקציה יכולה להחזיר ערך‪ ,‬לא להחזיר כלום‪ ,‬או להחזיר מספר טיפוסים שונים במקרים‬
‫שונים‪ ,‬וזאת מבלי לשנות את ההגדרה שלה (ה‪ Prototype -‬שלה)‪.‬‬
‫כמו כן‪ ,‬חוקי ה‪ Case Sensitivity-‬זהים לאלו של משתנים – יש הבדל בין אותיות גדולות וקטנות (לדוגמה‪ ,‬פונקציה בשם ‪f‬‬
‫איננה זהה לפונקציה בשם ‪.)F‬‬
‫הגדרת פונקציה פשוטה (בלי פרמטרים)‪:‬‬

‫‪>>> def func():‬‬


‫‪...‬‬ ‫”‪print “I am a function‬‬
‫)(‪>>> func‬‬
‫‟‪„I am a function‬‬

‫‪ .)return‬אם ניקח את ערך ההחזרה של‬ ‫הפונקציה הזו לא מקבלת שום פרמטר‪ ,‬וגם לא מחזירה כלום (אין בה משפט‬
‫הפונקציה ונשים אותו בתוך משתנה‪ ,‬המשתנה יכיל "כלום"‪:‬‬

‫)(‪>>> h = func‬‬
‫‟‪„I am a function‬‬
‫‪>>> h‬‬
‫>>>‬

‫וכמו שניתן לראות‪ ,‬כלום לא הודפס – המשתנה ‪ h‬מכיל "כלום"‪.‬‬


‫ה‪"-‬כלום" הזה מכונה ב‪ None .”None “ Python-‬הוא עצם יחיד ( ‪ ,)Singleton‬שמצביעים אליו כשרוצים לציין שאין לנו למה‬
‫להצביע‪ None .‬לא אומר שאין לנו מה להחזיר (כמו ב‪ ,)C -‬אלא אומר שאנחנו לא מחזירים כלום (או ליתר דיוק‪ ,‬מחזירים‬
‫"כלום")‪ .‬כמו כן‪ None ,‬הוא ערך חוקי לכל דבר‪ ,‬וניתן להשים אותו למשתנים באותו האופן שניתן להחזיר אותו‬
‫מפונקציות‪.‬‬
‫על‪-‬מנת שפונקציה תחזיר ‪ ,None‬ניתן לעשות שלושה דברים‪:‬‬
‫לא לרשום שום משפט ‪.return‬‬ ‫‪.1‬‬
‫לרשום שורה ובה המילה ‪ return‬בלבד‪.‬‬ ‫‪.2‬‬
‫לרשום את המשפט ‪.return None‬‬ ‫‪.3‬‬

‫‪ pass‬בפונקציות‬
‫כמו בלולאות‪ pass ,‬עובד יפה מאוד גם בפונקציות‪ .‬פשוט רושמים ‪ pass‬במקום בלוק הפונקציה‪:‬‬

‫‪def doing_nothing():‬‬
‫‪pass‬‬

‫פרמטרים‬
‫‪Default‬‬ ‫העברת הפרמטרים לפונקציות ב‪ Python-‬מאחדת למעשה את הנוחות של משתנים ב‪ Python-‬עם אפשרות ה‪-‬‬
‫‪ Value‬של ‪ .C++‬העברת פרמטרים תיעשה בסוגריים של הפונקציה‪:‬‬

‫‪def func_with_args(a, b, c):‬‬


‫‪pass‬‬

‫לפונקציה זו העברנו שלושה פרמטרים‪ ,b ,a :‬ו‪ .c -‬כמו שניתן לראות‪ ,‬אין צורך בטיפוס‪ ,‬כי ב‪ Python-‬משתנה יכול להיות‬
‫מכל טיפוס שהוא‪ .‬כמובן‪ ,‬זה לא אומר שניתן להעביר כל סוג משתנה שהוא לפונקציה‪ ,‬הרי היא מצפה לסוג משתנה‬
‫מסוים‪ .‬אם לא נוהגים בחופש זה בזהירות‪ ,‬ניתן לגרום לכל תוכנית פשוטה לקרוס ממש מהר‪.‬‬
‫הפרמטרים שמועברים לפונקציה מועברים אליה ‪ ,By Value‬כלומר נוצר עותק של המשתנה עבור הפונקציה‪ ,‬והמשתנים‬
‫מצביעים לעותק זה‪ .‬כמובן שעבור רצפים (רשימות וכו') אין משמעות לעותק הנ"ל‪ ,‬כיוון שהוא מצביע לאותו אובייקט‪.‬‬
‫בעת היציאה מהפונקציה‪ ,‬יושמדו העותקים האלה (אלא אם כן הם יוחזרו ע"י הפונקציה‪ ,‬ואז יכול להיווצר עותק עבור‬
‫ערך ההחזרה‪ ,‬או שיוחזר העותק המקורי של הפונקציה – תלוי במימוש)‪.‬‬
‫ניתן לציין ערכי ‪ Default‬לפרמטרים‪ .‬החוקים לזה דומים לאלה שב‪ :C++ -‬המשתנים בעלי ערך ‪ Default‬חייבים להופיע‬
‫‪ Default‬יופיע פרמטר בלי ערך ‪ .)Default‬כמו כן‪ ,‬בעת‬ ‫כפרמטרים האחרונים (אי‪-‬אפשר שאחרי פרמטר בעל ערך‬
‫הקריאה לפונקציה‪ ,‬אי‪-‬אפשר להשאיר "פרמטרים ריקים" (כלומר‪ ,‬לשים פסיק כדי לדלג על משתנה‪ ,‬בניגוד ל‪,BASIC -‬‬
‫בה מותר לעשות דבר כזה)‪ ,‬וחובה להעביר את כל הפרמטרים לפונקציה‪.‬‬
‫כמובן‪ ,‬דוגמה‪:‬‬

‫>>>‬ ‫‪def func_with_defaults(x, y = 5, z = 17):‬‬


‫‪...‬‬ ‫‪print x, y, z‬‬
‫>>>‬ ‫)‪func_with_defaults(1‬‬
‫‪1 5‬‬ ‫‪17‬‬
‫>>>‬ ‫)‪func_with_defaults(1,4‬‬
‫‪1 4‬‬ ‫‪17‬‬
‫>>>‬ ‫)‪func_with_defaults(9,8,5‬‬
‫‪9 8‬‬ ‫‪5‬‬

‫וכאמור‪ ,‬אי‪-‬אפשר לרשום מוטציות מוזרות כמו‪:‬‬

‫)‪>>> func_with_defaults(1,,9‬‬
‫‪File “<stdin”>, line 1‬‬
‫)‪func(1,,9‬‬
‫‪SyntaxError: invalid syntax.‬‬

‫הדבר היחיד שחסר לנו‪ ,‬כדי להשלים את כל התכונות של פונקציות ב‪ C -‬ו‪ C++ -‬הוא ה‪( Ellipsis -‬כאשר שמים ‪ ...‬בסוף‬
‫)(‪ .)printf‬דבר זה ממומש ב‪Python-‬‬ ‫שורת הארגומנטים לפונקציה כדי להעביר מספר לא ידוע של פרמטרים‪ ,‬כמו ב‪-‬‬
‫בצורה הרבה יפה מאשר ב‪ :C -‬כאשר רוצים שפונקציה תקבל מספר לא ידוע של פרמטרים‪ ,‬פשוט מוסיפים עוד פרמטר‬
‫‪ Python‬לקחת את כל הפרמטרים שיתווספו אחרי‬ ‫אחד בסופה‪ .‬לפני שם הפרמטר שמים כוכבית‪ ,‬וזה אומר ל‪-‬‬
‫הפרמטרים הרגילים ולהפוך אותם ל‪ .Tuple-‬אחרי זה‪ ,‬העבודה מול ‪ Tuple‬היא כבר נוחה ופשוטה‪.‬‬

‫‪>>> def iddqd_idkfa(x, *t):‬‬


‫‪...‬‬ ‫‪print x‬‬
‫‪...‬‬ ‫‪print t‬‬
‫)‪>>> iddqd_idkfa(1, 2, 3, 4, 5‬‬
‫‪1‬‬
‫)‪(2, 3, 4, 5‬‬

‫בעיה קטנטנה שמתעוררת כאן היא כאשר יש לנו שתי פונקציות‪ ,‬ושתיהן מקבלות " ‪ "Ellipsis‬כזה בסופן‪ .‬מה יקרה כאשר‬
‫קראו לפונקציה אחת‪ ,‬והיא רוצה להעביר את כל רשימת הפרמטרים לפונקציה השניה‪ ,‬אבל לא כ‪ ,Tuple -‬אלא כרשימה‬
‫אמיתית‪ ,‬כאילו קראו לה עם רשימת הפרמטרים?‬
‫רק כדי להמחיש את הבעיה‪ ,‬הנה שתי הפונקציות‪:‬‬

‫‪>>> def yanti(x, *y):‬‬


‫‪...‬‬ ‫‪print x ,y‬‬
‫‪...‬‬ ‫)‪parazi(x, y‬‬
‫‪...‬‬
‫‪>>> def parazi(x, *y):‬‬
‫‪...‬‬ ‫‪print x, y‬‬
‫‪...‬‬

‫הנה מה שיקרה כאשר נקרא ל‪:yanti -‬‬

‫)‪>>> yanti(1, 2, 3‬‬


‫)‪1 (2, 3‬‬
‫) ‪1 ((2, 3),‬‬

‫מה שקרה כאן הוא שבעת הקריאה ל‪ Python ,yanti -‬המירה את הפרמטרים העודפים ל‪ ,Tuple -‬אליו מצביע הפרמטר ‪.y‬‬
‫כאשר ‪ yanti‬קראה ל‪ ,parazi -‬היא העבירה (כפרמטר עודף אחד!) את כל ה‪ ,Tuple -‬כי ה‪ Tuple -‬הוא הרי טיפוס‪ ,‬משתנה‬
‫אחד‪ ,‬בדיוק כמו מספר שלם או מחרוזת‪.‬‬
‫‪ Tuple‬שלה‪ ,‬אותו היא יוצרת עבור‬ ‫‪ parazi‬קיבלה את ה‪ Tuple -‬כפרמטר אחד‪ ,‬לקחה את הפרמטר והכניסה אותו ל‪-‬‬
‫הפרמטרים העודפים‪.‬‬
‫בקיצור‪ ,‬בעוד ש‪ parazi -‬ציפתה לקבל ‪ Tuple‬אחד‪ ,‬היא קיבלה ‪ Tuple‬בתוך ‪ – Tuple‬סלט של ‪-Tuple‬ים‪ ,‬וזה רק עם ‪2‬‬
‫פונקציות‪.‬‬
‫ברור שיש פה פתרון‪ ,‬והוא אפילו ממש פשוט‪ :‬בעת הקריאה ל‪ parazi -‬צריך לשים כוכבית לפני ‪ .y‬הכוכבית אומרת ל ‪-‬‬
‫‪ Python‬לקחת את ה‪ Tuple-‬הקיים כ‪ Tuple-‬של הפרמטרים העודפים‪ ,‬ולא ליצור ‪ Tuple‬חדש‪ .‬הנה הפונקציות המתוקנות‪:‬‬

‫‪>>> def yanti(x, *y):‬‬


‫‪...‬‬ ‫‪print x ,y‬‬
‫‪...‬‬ ‫)‪parazi(x, *y‬‬
‫‪...‬‬
‫‪>>> def parazi(x, *y):‬‬
‫‪...‬‬ ‫‪print x, y‬‬
‫‪...‬‬

‫והנה מה שיקרה כשנקרא ל‪ yanti-‬המשופצרת‪:‬‬


‫)‪>>> yanti(1, 2, 3‬‬
‫)‪1 (2, 3‬‬
‫)‪1 (2, 3‬‬

‫תיעוד‬
‫תיעוד (או באנגלית ‪ )Documentation‬הוא פעולה שאיננה כתיבת קוד‪ .‬תיעוד הוא כתיבת הערות לתוכניות שלנו כדי‬
‫שאנחנו‪ ,‬או אנשים אחרים‪ ,‬נוכל לקרוא הערות על הקוד ולהבין אותו‪ ,‬במקרה שהוא לא כל‪-‬כך מובן‪.‬‬
‫יש שני סוגים גדולים של תיעוד ב‪:Python-‬‬
‫סתם תיעוד שזורקים באמצע הקוד‪ ,‬כדי שיהיה יותר ברור‪.‬‬ ‫‪.1‬‬
‫מחרוזת תיעוד קבועה בתחילת הפונקציה‪.‬‬ ‫‪.2‬‬

‫הסוג הראשון נעשה בצורה פשוטה מאוד – כמו שב‪ C++ -‬יש את רצף התווים " ‪ "//‬שאומר שמעכשיו ועד סוף השורה יש‬
‫דברים שלא צריך לקמפל (שכנראה יהיו הערות והארות)‪ ,‬כך גם ב‪ Python-‬יש את התו "‪ "#‬שאומר שאין להתייחס למה‬
‫שכתוב מאחרי תו זה ואילך‪:‬‬

‫‪>>> def func():‬‬


‫‪...‬‬ ‫‪print “We have to write something” # ladod moshe hayta para‬‬

‫הסוג השני של תיעוד הוא סוג מיוחד‪ ,‬ואליו ‪ Python‬מתייחסת בצורה שונה – בתחילת פונקציה‪ ,‬שורה אחת אחרי שורת‬
‫ה‪( def-‬בלי שום רווחים מסתוריים)‪ ,‬ניתן לשים מחרוזת (כמובן‪ ,‬עם ‪ TAB‬לפניה)‪ .‬המחרוזת הזאת היא מחרוזת התיעוד של‬
‫הפונקציה‪ .‬כאשר מישהו אחר (או אנחנו) ירצה יום אחד לדעת מהי הפונקציה הזו‪ ,‬הוא יוכל לקבל את המחרוזת בקלות‬
‫רבה‪ .‬העובדה שהתיעוד נמצא בתוך הקוד עצמו הוא דבר מאוד חזק – זה אומר שאם יש לך את הקוד‪ ,‬יש לך את‬
‫התיעוד‪ .‬אין צורך לחפש קובץ תיעוד שנעלם‪ ,‬או יותר גרוע‪ ,‬איזו חוברת שקבורה במגירה של מישהו אחר‪ .‬מושג מחרוזות‬
‫התיעוד בתחילת פונקציות שאול משפת התכנות ‪ ,LISP‬וקרוי ‪( DocStrings‬או ‪)Documentation Strings‬‬

‫‪>>> def tor():‬‬


‫‪...‬‬ ‫”‪“I am a function that does absolutely nothing‬‬
‫‪...‬‬ ‫‪pass‬‬
‫‪...‬‬
‫)(‪>>> tor‬‬
‫__‪>>> tor.__doc‬‬
‫‟‪„I am a function that does absolutely nothing‬‬

‫אז את מחרוזת התיעוד מקבלים ע"י כתיבת שם הפונקציה‪ ,‬נקודה‪ ,‬ו‪.__doc__ -‬‬
‫אבל ברוב הפעמים נרצה לכלול יותר משורה אחת בתיעוד‪ ,‬שתכיל את מבנה הפונקציה‪ ,‬מה היא מחזירה‪ ,‬פרמטרים‪,‬‬
‫‪-’\n‬ים כאשר רוצים לרדת שורה‪ .‬אם‬ ‫תיאור מפורט‪ ,‬וכו'‪ .‬כדי לעשות את זה‪ ,‬כותבים את מחרוזת התיעוד‪ ,‬ומוסיפים ‘‬
‫רוצים לרדת שורה בתוך הקוד עצמו‪ ,‬ניתן לעשות את זה ע"י כתיבת \ בסוף השורה‪ ,‬והמשך מחרוזת התיעוד בשורה‬
‫הבאה‪.‬‬
‫בלי שום קשר‪ ,‬התו \ מורה ל ‪ Python-‬שהשורה הבאה היא המשך השורה הקודמת‪ .‬כמובן‪ ,‬השורה הבאה‪ ,‬שהיא המשך‬
‫השורה הקודמת‪ ,‬חייבת להיות בעלת אינדנטציה זהה לשורה שקדמה לה‪ ,‬אותה היא ממשיכה‪:‬‬

‫‪>>> def func_with_long_doc():‬‬


‫‪...‬‬ ‫\“‪“I have a very very very very very\n‬‬
‫‪...‬‬ ‫”‪“very very long documentation‬‬
‫‪...‬‬
‫__‪>>> func_with_long_doc.__doc‬‬
‫‟‪„I have a very very very very very\nvery very long documentation‬‬

‫כדי להדפיס את מחרוזת התיעוד כמו שצריך (ולא את תוכן המחרוזת עצמה)‪ ,‬נשתמש ב‪:print -‬‬

‫__‪>>> print func_with_long_doc.__doc‬‬


‫‪I have a very very very very very‬‬
‫‪very very long documentation‬‬

‫משתנים בפונקציות‬
‫לקינוח פרק זה‪ ,‬רק נכסה נושא אחד – מה קורה כאשר מכריזים על משתנים בתוך מקומות שונים בפונקציה‪.‬‬
‫המקרה הפשוט ביותר‪ ,‬כאשר כותבים פונקציה‪ ,‬ופתאום מכריזים בה על משתנה‪:‬‬

‫‪def func():‬‬
‫”‪print “Here we go‬‬
‫‪i = 9‬‬
‫‪while i > 0:‬‬
‫‪print i * 5‬‬

‫בפונקציה הזאת‪ ,‬הוכרז משתנה בשם ‪ .i‬המשתנה ‪ i‬יהיה קיים עד שהפונקציה תגיע לסופה‪ ,‬ואז יושמד‪ .‬אם נקרא‬
‫לפונקציות אחרות מתוך הפונקציה ‪ ,func‬הן לא יכירו את המשתנה ‪ .i‬יותר מכך‪ ,‬אם פונקציה אחרת תכריז על משתנה‬
‫באותו השם ‪ ,i‬לכ"א מהפונקציות יהיה משתנה ‪ i‬משלה‪:‬‬
‫‪>>> def alice():‬‬
‫‪...‬‬ ‫‪k = 3‬‬
‫‪...‬‬
‫‪>>> def bob():‬‬
‫‪...‬‬ ‫‪k = 1‬‬
‫‪...‬‬ ‫‪print k‬‬
‫‪...‬‬ ‫)(‪alice‬‬
‫‪...‬‬ ‫‪print k‬‬
‫‪...‬‬
‫)(‪>>> bob‬‬
‫‪1‬‬
‫‪1‬‬

‫בנוסף לכך‪ ,‬יכול להיות מקרה בו פונקציה יוצרת משתנה‪ ,‬אבל המשתנה לא נוצר בתוך הבלוק של הפונקציה‪ ,‬אלא‬
‫באחד מתת‪-‬הבלוקים שלה‪ ,‬בתוך תנאי ‪ if‬או לולאת ‪ for‬או ‪ .while‬במצב כזה‪ ,‬המשתנה שנוצר יהיה תקף וקיים גם אחרי‬
‫היציאה מתת‪-‬הבלוק‪ ,‬בלי שום קשר לזה שהוא נוצר בתוך הבלוק (בשונה מאוד מ‪ Scopes -‬ב‪ C-‬וב‪:)C++-‬‬

‫‪>>> def last_func_for_today():‬‬


‫‪...‬‬ ‫‪e = 3‬‬
‫‪...‬‬ ‫‪while e != 0:‬‬
‫‪...‬‬ ‫‪e -= 1‬‬
‫‪...‬‬ ‫‪if e == 2:‬‬
‫‪...‬‬ ‫‪g = 9.8‬‬
‫‪...‬‬ ‫‪print e, g‬‬
‫‪...‬‬
‫)(‪>>> last_func_for_today‬‬
‫‪0 9.8‬‬

‫החזרת ‪-Tuple‬ים מפונקציה‬


‫ב‪ Python-‬קיים טיפוס האנתונים ‪ .Tuple‬בפרק על טיפוסי הנתונים סקרנו את הטיפוס‪ ,‬וראינו שניתן לאגד מספר ערכים‬
‫ב‪ Tuple-‬אחד‪ .‬ניתן להשתמש בתכונה זו כדי להחזיר מספר ערכים מפונקציה‪ ,‬ע"י כך שמאגדים אותם ביחד ב‪.Tuple -‬‬
‫לדוגמה‪ ,‬הנה פונקציה שמחזירה שני ערכים‪:‬‬

‫‪>>> def f():‬‬


‫‪...‬‬ ‫)'‪return ('bibibim', 'bobobom‬‬

‫כאשר נשתמש בפונקציה‪ ,‬נוכל לקבל ממנה מיד את שני הערכים לתוך שני משתנים‪:‬‬

‫)(‪>>> str1, str2 = f‬‬


‫‪>>> str1‬‬
‫'‪'bibibim‬‬
‫‪>>> str2‬‬
‫'‪'bobobom‬‬
‫פרק ‪map, reduce, filter, lambda_:7‬‬
‫כמו בכל שפת תכנות‪ ,‬ב‪ Python -‬יש הרבה מקרים בהם יש אוסף של נתונים (רשימה‪ ,‬תור‪ ,‬מחסנית‪ ,‬מערך‪ ,‬וכד') עליו‬
‫מבצעים עיבוד מסוים‪ .‬העיבוד יכול להיות כמעט כל דבר (קריאה לפונקציות‪ ,‬פעולות בין שני איברים עוקבים‪ ,‬וכד')‪.‬‬
‫ברוב המקרים‪ ,‬העיבוד הזה ייעשה בלולאה‪.‬‬
‫בשביל המקרים האלה נוצרו הפונקציות ‪ reduce ,map‬ו‪.filter-‬‬

‫שלוש הפונקציות האלה הן פונקציות מובנות ב‪ ,Python -‬שכל מטרתן היא לקחת רשימה (או ‪ ,)Tuple‬להריץ פונקציה על‬
‫האיברים שלה (כ"א משלוש הפונקציות מריצה את הפונקציה בדרך שונה‪ ,‬עם איבר או איברים שונים) ולהפיק פלט‬
‫מתאים‪.‬‬
‫כל זה נעשה ע"י קריאה לפונקציה אחת על הרשימה‪ ,‬דבר שחוסך כתיבה מחדש של לולאה טריוויאלית בכל פעם‬
‫מחדש (ולפעמים קצת יותר מלולאה טריוויאלית)‪.‬‬

‫‪map‬‬
‫פונקצית קסם ראשונה‪.‬‬
‫‪ map‬מקבלת רשימה ופונקציה‪ .‬הפונקציה חייבת לקבל פרמטר אחד בלבד‪ map .‬מריצה את הפונקציה עם כ"א מאיברי‬
‫הרשימה (כל איבר בתורו‪ ,‬לפי הסדר בו הם מופיעים ברשימה)‪.‬‬
‫‪ map‬מחזירה רשימה חדשה‪ ,‬ובה כל איבר הוא התוצאה של הפונקציה עם האיבר המתאים לו ברשימה המקורית‪.‬‬
‫בעברית‪ map :‬לוקחת את האיבר הראשון‪ ,‬מריצה עליו את הפונקציה‪ ,‬ושמה את התוצאה ברשימה החדשה‪ .‬אח"כ היא‬
‫לוקחת את האיבר השני‪ ,‬מריצה עליו את הפונקציה‪ ,‬ושמה את התוצאה באיבר הבא ברשימה החדשה‪ .‬כך היא עושה‬
‫לכל האיברים‪.‬‬

‫‪>>> def func(x):‬‬


‫‪...‬‬ ‫‪return x * 2‬‬
‫‪...‬‬
‫))‪>>> map(func, range(1, 11‬‬
‫]‪[2, 4, 6, 8, 10, 12, 14, 16, 18, 20‬‬

‫‪reduce‬‬
‫פונקצית קסם שניה‪.‬‬
‫‪ reduce‬מקבלת רשימה ופונקציה‪ .‬הפונקציה חייבת לקבל שני פרמטרים‪ reduce .‬לוקחת את שני האיברים הראשונים‬
‫ברשימה ומריצה את הפונקציה כאשר האיבר הראשון הוא הפרמטר הראשון והאיבר השני הוא הפרמטר השני של‬
‫הפונקציה‪ .‬לאחר מכן‪ reduce ,‬לוקחת את התוצאה של הפונקציה ומריצה את הפונקציה עם התוצאה כפרמטר הראשון‬
‫והאיבר הבא מהרשימה כפרמטר השני‪ .‬כך היא ממשיכה עד סוף הרשימה‪.‬‬
‫אם ברשימה יש רק איבר אחד‪ reduce ,‬תחזיר את האיבר היחיד ברשימה (מבלי להריץ את הפונקציה)‪ .‬אם הרשימה‬
‫ריקה‪ reduce ,‬תקרוס ותדפיס הודעת שגיאה‪.‬‬

‫‪>>> def func(x, y):‬‬


‫‪...‬‬ ‫‪return x + y‬‬
‫‪...‬‬
‫))‪>>> reduce(func, range(1, 11‬‬
‫‪55‬‬

‫בדוגמה הזו הודפס הסכום של כל המספרים בין ‪ 1‬ל‪.10-‬‬

‫‪filter‬‬
‫פונקצית קסם שלישית‪.‬‬
‫‪ filter‬תיקח כ"א מאיברי הרשימה ותריץ את‬ ‫‪ filter‬מקבלת רשימה ופונקציה‪ .‬הפונקציה חייבת לקבל פרמטר אחד‪.‬‬
‫הפונקציה עם האיבר הזה‪ .‬אם התוצאה של ריצת הפונקציה היא ‪( TRUE‬איננה אפס‪ ,‬איננה מחרוזת ריקה‪ ,‬ולא הופכת‬
‫לאפס אם עושים לה ‪ Casting‬ל‪ ,)Integer-‬האיבר (האיבר מהרשימה שהועברה ל‪ ,filter -‬לא ערך ההחזרה של הפונקציה)‬
‫יתווסף לרשימת התוצאה‪.‬‬
‫‪ filter‬למעשה מאפשרת לנו לסנן ערכים מרשימה נתונה‪ ,‬בשורה אחת בלבד‪.‬‬

‫‪>>> def func(x):‬‬


‫‪...‬‬ ‫‪return x % 2‬‬
‫‪...‬‬
‫>>>‬
‫))‪>>> filter(func, xrange(20‬‬
‫]‪[1, 3, 5, 7, 9, 11, 13, 15, 17, 19‬‬

‫בדוגמה הזו הודפסו כל המספרים בין ‪ 0‬ל‪ 19 -‬ששארית החלוקה שלהם ב‪ 2 -‬איננה אפס‪ .‬בקיצור‪ ,‬כל המספרים האי‪-‬‬
‫זוגיים‪.‬‬
‫ניתן כמובן להפוך את התנאי ולהדפיס את כל המספרים הזוגיים‪:‬‬

‫‪>>> def func(x):‬‬


‫‪...‬‬ ‫‪return not x % 2‬‬
‫‪...‬‬
‫))‪>>> filter(func, xrange(20‬‬
‫]‪[0, 2, 4, 6, 8, 10, 12, 14, 16, 18‬‬

‫‪lambda‬‬
‫אז מה ‪ lambda‬עושה בכלל ולמה היא קשורה לפרק הזה?‬
‫‪ reduce ,map‬או ‪ filter‬היינו צריכים לכתוב פונקציה‬ ‫כמו שאפשר לראות בדוגמאות למעלה‪ ,‬עבור כ"א מההרצות של‬
‫חדשה כדי שנוכל להעביר פונקציה לכ"א מהפונקציות‪ .‬אבל כתיבת פונקציה חדשה כל פעם זה סתם העמסה על‬
‫הקוד‪ ,‬ולפעמים גם יכול להיות מסובך למצוא את הפונקציה (אם שמנו אותה במקום אחר)‪.‬‬
‫‪ lambda‬מאפשרת לנו לחסוך עוד יותר בכמות הקוד – במקום לכתוב פונקציה חדשה בכל פעם‪ lambda ,‬יוצרת עבורנו‬
‫פונקציה ללא‪-‬שם‪ ,‬כבר בתוך שורת הקוד של ‪ reduce ,map‬או ‪.filter‬‬
‫בת'כלס‪ ,‬כאשר יוצרים פונקציה‪ ,‬השם שנותנים לפונקציה הוא מצביע לפונקציה עצמה‪ .‬זאת גם הסיבה שכאשר כותבים‬
‫שם של פונקציה‪ ,‬בלי סוגריים‪ Python ,‬כותבת לנו את שם הפונקציה‪ .‬באופן הזה‪ lambda ,‬יוצרת עבורנו פונקציה חדשה‪,‬‬
‫ומחזירה את המצביע לפונקציה החדשה‪ .‬לפונקציה החדשה אין שם‪ ,‬וכאשר תסתיים הרצת ‪ reduce ,map‬או ‪ ,filter‬גם‬
‫הפונקציה חסרת‪-‬השם תימחק‪.‬‬
‫דוגמה קטנה כדי להבין יותר טוב מה קורה‪:‬‬

‫יצרנו פונקציה חדשה‬

‫‪>>> def func():‬‬ ‫הנה הכתובת שלה‬


‫‪...‬‬ ‫‪return 5‬‬
‫‪...‬‬
‫‪>>> func‬‬
‫>‪<function func at 0x00AD57A0‬‬ ‫וזו הכתובת של פונקצית ‪lambda‬‬
‫‪>>> lambda x:x + 2‬‬ ‫חדשה שזה הרגע נוצרה‪.‬‬
‫>‪<function <lambda> at 0x00AFB3D0‬‬

‫קצת על המבנה של ‪ :lambda‬כתיבת פונקצית ‪ lambda‬למעשה כולל רק את הפרמטרים לפונקציה ואת ערך ההחזרה‬
‫שלה‪ ,‬כי למעשה אין צורך ביותר מכך (פונקציות ‪ lambda‬הן ל"שימוש חד‪-‬פעמי"(‪.‬‬
‫והנה דוגמה לשימוש ב‪ map -‬ו‪ lambda -‬ביחד‪ .‬הדוגמה עושה את מה שעושה הדוגמה הראשונה – מקבלת רשימת‬
‫מספרים ומחזירה רשימה של האיברים המקוריים כפול ‪:2‬‬

‫))‪>>> map(lambda x:x*2, range(1, 11‬‬


‫]‪[2, 4, 6, 8, 10, 12, 14, 16, 18, 20‬‬

‫‪ – x‬ומחזירה את ‪ .x*2‬כמובן‪ ,‬אפשר לכתוב כל ביטוי‬ ‫בדוגמה הזו נכתבה פונקצית ‪ lambda‬המקבלת פרמטר אחד –‬
‫שתלוי ב‪ ,x-‬ואפשר גם לכלול פונקציות בביטוי הזה‪.‬‬

‫למעשה‪ ,‬כאשר אנו כותבים את פונקציית ה‪ lambda-‬הבאה‪:‬‬

‫‪>>> f = lambda x: x * 2‬‬

‫יצרנו פונקציה‪ ,‬אותה יכולנו ליצור באופן הבא‪:‬‬

‫‪>>> def f(x):‬‬


‫‪...‬‬ ‫‪return x * 2‬‬
‫‪...‬‬

‫התוצאה היא זהה לחלוטין בשני המקרים‪.‬‬

‫שימוש ב‪ reduce ,map-‬ו‪ filter-‬ביחד‬


‫שלוש הפונקציות לבדן אינן הסוף – אפשר לשלב כמה פונקציות כאלה ביחד‪ :‬למשל‪ ,‬התוצאה של ‪ map‬תהיה הרשימה‬
‫של ‪ ,filter‬וכד'‪.‬‬
‫הנה שתי דוגמאות לשימושים כאלה‪:‬‬

‫פונקציה שמחזירה האם מספר הוא ראשוני‪:‬‬

‫‪def is_primary(n):‬‬
‫)))‪return reduce(lambda x, y: x and y, map(lambda x: n % x, range(2, n‬‬
‫פונקציה שמחזירה את סכום הספרות במספר‪:‬‬

‫‪def sum_of_digits(n):‬‬
‫))))‪return reduce(lambda x,y:x+y, map(int, map(None, str(n‬‬

‫מילה על יעילות‬
‫ישנה כמובן השאלה – מה יעיל יותר‪ ,‬להשתמש בלולאה רגילה ( ‪ ,)for ,while‬או להשתמש (כשאפשר) ב‪reduce ,map -‬‬
‫או ‪?filter‬‬
‫כנראה (עקב מימוש) יעיל יותר להשתמש ב‪ reduce ,map -‬ו‪ filter -‬במקום בלולאה רגילה בגלל שהפונקציות עצמן‬
‫ממומשות ב‪ ,C -‬או בכל שפה עילית אחרת‪ .‬היות והמימוש הוא בשפה נמוכה יותר מ‪ ,Python -‬הריצה שלה תהיה מהירה‬
‫יותר‪.‬‬
‫מהכיוון ההפוך – כאשר מריצים לולאה רגילה ב‪ ,Python -‬יש צורך באחזקת משתנה ( ‪ i‬לצורך הענין)‪ ,‬או רשימה ( ‪range‬‬
‫לסוגיה)‪ .‬האחזקה הזו לוקחת גם זיכרון וגם עיבוד נוסף (שנסתר ונחסך מהמתכנת)‪ ,‬ולכן היא "יקרה" יותר‪.‬‬
‫‪ ,C‬אלא כדי להדגיש ששימוש‬ ‫השאלה הזו לא מוצגת כדי שנחשוב טוב טוב לפני שכותבים משהו ב‪ Python-‬או ב‪-‬‬
‫בפונקציות פנימיות הוא לרוב מהיר יותר‪ .‬כמו כן‪ ,‬לא צריך להשתגע ולכתוב תוכניות שלמות עם קריאות מסובכות ל‪-‬‬
‫‪ reduce ,map‬ו‪.filter-‬‬
‫טוב להשתמש ב"קיצורי דרך"‪ ,‬כל עוד הם גם משפרים את התוכנית‪ ,‬הופכים אותה לקריאה יותר וקלה יותר ל‪.Debug-‬‬
‫פרק ‪_:8‬מודולים‬
‫מהו מודול?‬
‫מודול‪ ,‬בדומה לפונקציה‪ ,‬הוא יחידה המאחסנת בתוכה קוד לשימוש חוזר‪ .‬ב‪ Python-‬קיימות מספר דרכים ליצור מצב בו‬
‫קוד נמצא בקובץ אחר וניתן להשתמש בו בקוד אחר (או לצורך הענין ישירות ב‪.)Interpreter -‬‬
‫בפרק זה נתמקש בשלוש דרכים עיקריות בהן משתמשים לרוב כאשר רוצים להשתמש בקוד קיים מחדש‪.‬‬

‫אוסף פונקציות שנמצא בקובץ אחר‬


‫דרך אחת לכתוב מודול היא לכתוב קובץ טקסט רגיל‪ ,‬ובו יהיו פונקציות שונות ב‪ .Python-‬כמובן‪ ,‬הפונקציות ייכתבו לפי‬
‫כל חוקי הכתיבה של ‪ ,Python‬ויאוחסנו בקובץ‪ .‬כאשר נרצה להשתמש בפונקציות‪ ,‬נצטרך "לטעון" אותן לסביבת‬
‫העבודה שלנו‪.‬‬
‫הטעינה לסביבת העבודה יכולה להתבצע ע"י הפונקציה המובנית )(‪ .execfile‬תפקידה של הפונקציה הוא לקחת קובץ‬
‫טקסט קיים‪ ,‬ולבצע אותו‪ ,‬שורה אחרי שורה‪ ,‬כאילו המשתמש הרגע כתב אותו בעצמו ב‪.Interpreter -‬‬
‫לדוגמה‪ ,‬הנה קובץ טקסט מוכן מראש‪:‬‬

‫‪def func1(x):‬‬
‫))‪return map(lambda i: i * 2, xrange(0, x‬‬

‫‪def func2(x):‬‬
‫‪return 2L ** x‬‬

‫‪def func3(x):‬‬
‫‪return “The number is %d” % x‬‬

‫‪def func4(x):‬‬
‫‪return [x] * x‬‬

‫ולאחר ההרצה‪:‬‬
‫)‟‪>>> execfile(„c:\\example.py‬‬
‫)‪>>> func2(32‬‬
‫‪4294967296L‬‬

‫בנוסף‪ ,‬הפונקציה )(‪ execfile‬יכולה גם להריץ סתם קוד שמצוי בקובץ אחר‪ ,‬בלי שום קשר לפונקציות או כל דבר אחר‬
‫שנמצא בקובץ‪ .‬לדוגמה‪ ,‬הנה קובץ‪:‬‬

‫)“ >‪str_user = raw_input(“username --‬‬


‫)“ >‪str_pass = raw_input(“password --‬‬
‫‪if str_user == „monty‟ and str_pass == „python‟:‬‬
‫‟!‪print „Welcome‬‬
‫‪user_logged = 1‬‬
‫‪else:‬‬
‫‟‪print „Sorry.‬‬
‫‪user_logged = 0‬‬

‫והנה דוגמה לשימוש חוזר של קטע הקוד בפונקציה חדשה‪:‬‬

‫‪>>> def login():‬‬


‫‪...‬‬ ‫)‟‪execfile(„c:\\up.py‬‬
‫‪...‬‬ ‫‪if user_logged == 1:‬‬
‫‪...‬‬ ‫”‪print “Main menu‬‬
‫‪...‬‬ ‫“‪print “---------‬‬
‫‪...‬‬ ‫”‪print “1. ...‬‬
‫‪...‬‬ ‫”‪print “2. ...‬‬
‫‪...‬‬ ‫”‪print “3. ...‬‬
‫‪...‬‬
‫)(‪>>> login‬‬
‫‪username --> monty‬‬
‫‪password --> python‬‬
‫!‪Welcome‬‬
‫‪Main menu‬‬
‫‪1. ...‬‬
‫‪2. ...‬‬
‫‪3. ...‬‬
‫>>>‬
‫הרצת קבצי ‪ Python‬כמו תוכניות‬
‫קיימות סביבות עבודה למערכות ‪ Windows‬שמאפשרות הרצת קבצים עם סיומת ‪ ,py‬שזוהי סיומת עבור קבצי ‪.Python‬‬
‫‪ ,py‬ולכן אין צורך בשום‬ ‫השימוש הוא די פשוט‪ ,‬מכיוון שהתוכנה רושמת את עצמה בעת ההתקנה כמפעילה קבצי‬
‫כיוונים מעבר לכך‪.‬‬
‫אם אין לך ‪ ,Unix‬ואינך רוצה ללמוד איך להפעיל תוכנית ‪ Python‬על ‪ ,Unix‬אפשר לדלג על סעיף זה‪ .‬בכל מקרה‪ ,‬כדאי‬
‫להתנסות קצת ב‪ Python-‬על ‪ ,Unix‬גם אם אתה לא ממש מבין חלק מהמושגים בסעיף זה‪.‬‬
‫‪ ,)Linux‬יש צורך בכיוון של התוכנית‬ ‫במערכות ‪ Unix‬למיניהן (מומלץ ‪ ,Linux‬כי ‪ Python‬כבר בא עם רוב ההפצות של‬
‫שמריצה את קובץ ה‪ .py -‬כיוונון זה נעשה כמו ב‪ ,Perl -‬ע"י כתיבת תוכנית הפעלה כשורת ‪ Comment‬בשורה הראשונה‪.‬‬
‫כמו כן‪ ,‬יש לסמן את הקובץ כקובץ ‪ executable‬עם ‪.chmod‬‬
‫הנה קובץ ממש קצר לדוגמה (כאשר ההנחה היא שהתוכנה המריצה נמצאת ב‪ ,/usr/local/bin/python -‬ושם היא נמצאת‬
‫ברוב ה‪ Distributions-‬של ‪:)Linux‬‬

‫‪#!/usr/local/bin/python‬‬

‫”?‪print “what‟s your cat name‬‬


‫)“(‪cat_name = raw_input‬‬

‫”?‪print “what‟s your dog name‬‬


‫)“(‪dog_name = raw_input‬‬

‫)‪print “you have a dog named %s and a cat named %s!” % (dog_name, cat_name‬‬

‫והנה הוא רץ‪:‬‬

‫‪~$ ./quick_script.py‬‬
‫?‪what‟s your cat name‬‬
‫‪bush‬‬
‫?‪what‟s your dog name‬‬
‫‪charly‬‬
‫!‪you have a dog named charly and a cat named bush‬‬

‫באופן כללי‪ ,‬מאוד נוח לכתוב ‪-Script‬ים שרצים ב‪ Unix -‬כמו תוכניות רגילות‪ .‬ניתן להרחיב תוכניות כאלה עם פרמטרים‬
‫ב‪ )argv[]( Command Line-‬ועוד הרבה דברים שמקלים על התכנות‪.‬‬

‫כתיבת מודולים של ממש‬


‫שני הסעיפים הקודמים הם מעין דרכי‪-‬קיצור אם מה שצריך לכתוב הוא לא ממש מודול‪ ,‬או שהוא קצר מאוד‪ ,‬אם צריך‬
‫סתם לבדוק משהו קטן‪ ,‬וכד'‪.‬‬
‫מודול אמיתי‪ ,‬לעומת זאת‪ ,‬הוא אוסף של פונקציות (ולעיתים משתנים) המיוצאים החוצה מהמודול‪ ,‬כך שצריך לציין את‬
‫שם המודול בתוכנית המקורית‪ ,‬וניתן להתייחס לשגרות‪ ,‬משתנים‪ ,‬טיפוסים ואובייקטים (שיילמדו בפרקים הבאים)‬
‫שנמצאים במודול‪.‬‬
‫כל זה לא נעשה בצורות שונות ממה שהכרנו עד כה‪ ,‬ההבדל הוא בצורה בה הפונקציות מיובאות לתוך הקוד שלנו‪.‬‬
‫הנה הקובץ מהסעיף השני בפרק זה‪:‬‬

‫‪def func1(x):‬‬
‫))‪return map(lambda i: i * 2, xrange(0, x‬‬

‫‪def func2(x):‬‬
‫‪return 2L ** x‬‬

‫‪def func3(x):‬‬
‫‪return “The number is %d” % x‬‬

‫‪def func4(x):‬‬
‫‪return [x] * x‬‬

‫בקובץ זה ‪ 4‬פונקציות‪ ,‬כאשר שם הקובץ בו הן מאוחסנות הוא ‪ .example.py‬ייבוא הקובץ לתוך התוכנית שלנו (או לצורך‬
‫הדוגמה‪ ,‬ל‪ )Interpreter-‬ייעשה באמצעות הפקודה ‪.import‬‬
‫לפקודה ‪ import‬שתי צורות עיקריות‪ ,‬כאשר כל‪-‬אחת מהן תשפיע בדרך מסוימת על האופן בו הפונקציות ייובאו למודול‪.‬‬
‫‪ namespace‬הגלובלי‪ .‬המשמעות היא שכאשר נרצה‬ ‫צורה ראשונה מאפשרת ייבוא כל הפונקציות מהמודול לתוך ה‪-‬‬
‫להשתמש בפונקציה מהמודול‪ ,‬פשוט נכתוב את השם שלה‪.‬‬
‫צורה שניה היא ייבוא המודול ל‪ namespace -‬משלו‪ ,‬וכאשר נרצה להשתמש בפונקציה מהמודול‪ ,‬נצטרך לרשום את שם‬
‫המודול ושם הפונקציה‪ .‬צורה זו בטוחה יותר ודואגת שלא יהיו התנגשויות בין שמות פונקציות ממודולים שונים‪.‬‬
‫כאשר יש משתנים גלובליים מיוצאים ממודול‪ ,‬תמיד יש לכתוב גם את שם המודול וגם את שם המשתנה בפנייה אליו‪,‬‬
‫בלי קשר לצורת ייבוא המודול‪.‬‬
‫לדוגמה‪ ,‬הנה קוד שמייבא את ‪ examply.py‬ע"י הכנסתה ל‪ namespace-‬משלה‪:‬‬

‫‪>>> import example‬‬


‫)‪>>> example.func1(2‬‬
‫]‪[0, 2‬‬
‫)‪>>> example.func3(65‬‬
‫'‪'The number is 65‬‬
‫)‪>>> example.func4(17‬‬
‫]‪[17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17‬‬

‫‪ .py‬כמו כן‪ ,‬הפונקציות מיובאות לתוך‬ ‫כפי שניתן לראות‪ ,‬אין לכתוב את שם הקובץ כולו‪ ,‬אלא להשמיט את הסיומת‬
‫‪ namespace‬ששמו הוא כשם המודול‪ .‬ה ‪ namespace‬הנ"ל הינו בעצם אובייקט מסוג "מודול"‪ ,‬כלומר אובייקט המדמה את‬
‫המודול כאשר אבריו הם השמות והאובייקטים המיוצאים ממנו‪.‬‬
‫הקוד הבא מייבא את ‪ example.py‬ל‪ namespace-‬הגלובלי‪:‬‬

‫* ‪>>> from example import‬‬


‫)‪>>> func1(2‬‬
‫]‪[0, 2‬‬
‫)‪>>> func2(5‬‬
‫‪32L‬‬
‫)‪>>> func3(7‬‬
‫'‪'The number is 7‬‬

‫‪ ,example‬ולכן‬ ‫מבנה פקודת ה‪ import -‬במקרה הזה הוא יותר מורכב‪ .‬בדוגמה הזו בוצע ייבוא לכל הפונקציות במודול‬
‫הסימן *‪ .‬ניתן לבצע ייבוא שכולל רק חלק מהפונקציות במודול‪ .‬כמו כן‪ ,‬הפונקציות יובאו כך שניתן לקרוא להן כאילו‬
‫הן הוגדרו הרגע ב‪( Interpreter-‬או בקוד בו עובדים)‪.‬‬
‫כאשר כותבים תוכניות גדולות‪ ,‬קבצי ‪ Script‬וכד'‪ ,‬מקובל לשים את פקודות ה‪ import -‬בתחילת הקובץ‪ ,‬בדומה ל‪include -‬‬
‫ב‪.C-‬‬

‫דוגמה נוספת ל‪ import-‬היא ייבוא של מספר פונקציות ספציפיות ממודול‪ ,‬ולא את כל הפונקציות מהמודול‪:‬‬

‫‪>>> from example import func1, func2‬‬


‫)‪>>> func1(6‬‬
‫]‪[0, 2, 4, 6, 8, 10‬‬
‫)‪>>> func2(4‬‬
‫‪16L‬‬
‫)‪>>> func3(7‬‬
‫‪Traceback (most recent call last):‬‬
‫? ‪File "<stdin>", line 1, in‬‬
‫‪NameError: name 'func3' is not defined‬‬

‫ניתן לראות כי ‪ func1‬ו‪ func2-‬יובאו מ‪ ,example-‬אבל ‪ func3‬לא מוכרת כלל משום שצויין לייבא רק את ‪ func1‬ו‪.func2-‬‬

‫מודולים מובנים ב‪Python-‬‬


‫‪ Python‬מגיעים הרבה מודולים‪ ,‬ואת חלקם נסקור‬ ‫נושא אחרון לפרק זה הוא המודולים שכבר קיימים ב‪ .Python-‬עם‬
‫בפרק הבא‪ .‬ייבוא המודולים (או חלק מהפונקציות שבהם) נעשה ע"י שימוש ב‪ import-‬בדיוק כמו בדוגמאות הקודמות‪.‬‬

‫לדוגמה‪ ,‬בפרק זה נראה שימוש במודול ‪ ,math‬והפונקציות ‪ floor‬ו‪ ceil -‬שבו‪ floor .‬מקבלת מספר עשרוני ומחזירה מספר‬
‫עשרוני בו החלק של השבר הוא אפס‪ ceil .‬מקבלת מספר עשרוני ומעגלת אותו כלפי מעלה‪:‬‬

‫>>>‬ ‫‪import math‬‬


‫>>>‬ ‫‪y=5.4‬‬
‫>>>‬ ‫)‪math.floor(y‬‬
‫‪5.0‬‬
‫>>>‬ ‫)‪math.ceil(y‬‬
‫‪6.0‬‬

‫‪dir‬‬
‫ב‪ Python-‬קיימת פונקציה מובנית בשם ‪ .dir‬פונקציה זו מקבלת בפרמטר שם של מודול או מחלקה (מחלקות יילמדו‬
‫בהמשך) ומדפיסה את כל הפונקציות והמשתנים של המודול הנתון‪ .‬פונקציה זו שימושית מאוד בעבודה עם מודולים‪.‬‬
‫לדוגמה‪ ,‬הנה כל הפונקציות במודול ‪:math‬‬

‫)‪>>> dir(math‬‬
‫‪['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',‬‬
‫‪'cosh', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',‬‬
‫]'‪'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh‬‬
‫פרק ‪_:9‬ספריות נפוצות‬
‫הגרסאות העדכניות של ‪ Python‬מסופקות עם המון (ממש המון) ספריות לשימוש של המתכנתים בה‪ .‬ידע והכרה של‬
‫הספריות חשובים לא פחות מהכרה של השפה‪ ,‬בגלל שכמו ש‪ Python-‬חוסכת זמן בתכנות ומאפשרת כתיבה של‬
‫תוכניות חכמות וקצרות בהרבה‪ ,‬כך גם הספריות שמסופקות איתה – הן כוללות הרבה מחלקות (את נושא המחלקות‬
‫נלמד בהמשך) ופונקציות לשימושים חוזרים‪ ,‬וחוסכות זמן בבניה של כלים שכבר קיימים ומוכנים לשימוש‪.‬‬
‫פרק זה מכסה ‪ 4‬ספריות אותן נוח ללמוד בהתחלת העבודה עם מודולים חיצוניים‪ ,‬כי הן כוללות הרבה פונקציות שכבר‬
‫קיימות בשפות אחרות‪ ,‬ויותר נוח לראות כיצד מתבצעת ההקבלה ל‪ .Python-‬אבל‪ ,‬בגרסאות העדכניות של ‪ Python‬יש‬
‫‪Regular‬‬ ‫עשרות ספריות שונות ומשונות‪ ,‬ובהן ניתן למצוא הרבה מימושים של דברים שקיימים בשפות אחרות (כמו‬
‫‪ Expressions‬מ‪ Perl-‬או מודול ל‪ ,)Random-‬או פונקציות לקישור למערכת ההפעלה (כמו מודול ה‪ Socket -‬שמאפשר ליצור‬
‫‪-socket‬ים לתקשורת באינטרנט)‪ ,‬והרבה מעבר לכך‪.‬‬
‫שוב‪ ,‬הפרק לא מכסה את כל הפונקציות‪ ,‬אלא רק פונקציות מעניינות‪ ,‬ושוב‪ ,‬במטרה לתת מבוא והסברים לדברים‬
‫שעלולים להיות לא מובנים‪ ,‬ולא כדי לתרגם את התיעוד לעברית‪.‬‬
‫מומלץ לרפרף על התיעוד של הספריות הקיימות (למשל בתיעוד של ‪ ActivePython‬ל‪ )Windows -‬כדי לראות מה כבר‬
‫קיים‪.‬‬

‫ספריית ‪os‬‬
‫ספרייה זו מכילה פונקציות לתקשורת עם מערכת ההפעלה‪ .‬המודול לא תלוי במערכת ההפעלה עליה מורצת תוכנית‬
‫ה‪ .Python-‬קיימות הספריות ‪ nt‬ו‪ posix -‬לתקשורת עם מערכות הפעלה ‪ Windows-NT‬ו‪-UNIX -‬ים למיניהם‪ ,‬אבל ‪ os‬מכילה‬
‫פונקציות ומשתנים שיעבדו על כל מערכת‪.‬‬
‫כדי לכלול את המודול נכתוב‪:‬‬

‫‪>>> import os‬‬

‫בתוך המודול קיים משתנה ‪ name‬המכיל את שם מערכת‪-‬ההפעלה עליה מורצת ‪:Python‬‬

‫‪>>> os.name‬‬
‫‟‪„nt‬‬

‫המשתנה יכיל את סוג מערכת ההפעלה‪ ,‬ולא שם מלא כמו " ‪ "Windows 95‬וכד'‪ .‬כאשר ‪ Python‬מורצת על מערכת ‪,Java‬‬
‫‪ os.name‬יכיל את המחרוזת ‘‪.’java‬‬

‫‪.)temp‬‬ ‫המשתנה ‪ environ‬במודול הוא מילון המכיל את משתני הסביבה של המערכת (כמו המיקום של ספריית ה‪-‬‬
‫משתני הסביבה משתנים ממערכת למערכת‪ ,‬אך ניתן לראות את כל המשתנים הללו ע"י קריאה ל‪ keys() -‬של המילון‪:‬‬

‫)(‪>>> os.environ.keys‬‬
‫‪[„WINBOOTDIR', 'PATH', 'BLASTER', 'PATHEXT', 'TEMP', 'COMSPEC', 'PROMPT', 'WINDIR',‬‬
‫]‟‪'TMP‬‬

‫הפונקציה )(‪ system‬במודול מאפשרת להריץ פקודות של ה‪ Command Line -‬ולקבל את הפלט שלהן בערך ההחזרה של‬
‫הפונקציה‪ .‬שימוש נחמד יכול להריץ את הפקודה ‪:dir‬‬

‫‪>>> import os‬‬


‫)'‪>>> os.system('dir z:\\x‬‬
‫‪Volume in drive Z is Shared‬‬
‫‪Volume Serial Number is 0C17-3468‬‬

‫‪Directory of z:\x‬‬

‫‪07/31/2002‬‬ ‫‪10:08p‬‬ ‫>‪<DIR‬‬ ‫‪.‬‬


‫‪07/31/2002‬‬ ‫‪10:08p‬‬ ‫>‪<DIR‬‬ ‫‪..‬‬
‫)‪0 File(s‬‬ ‫‪0 bytes‬‬
‫‪2 Dir(s) 10,223,505,408 bytes free‬‬
‫‪0‬‬
‫>>>‬

‫הפונקציה למעשה מחזירה ערך‪ ,‬בדוגמה זהו ‪ ,0‬ובנוסף לכך מודפס למשך כל מה שהפקודה שלחה להדפסה למסך‪.‬‬
‫זאת הסיבה שהשורה האחרונה היא ‪ – 0‬זו לא השורה האחרונה‪ ,‬אלא ערך ההחזרה של הרצת הפקודה‪.‬‬

‫הפונקציה )(‪ mkdir‬ו‪ rmdir()-‬יוצרות ומוחקות ספריות‪ ,‬אבל ההבדל בין שימוש ב‪ sysetm() -‬כדי לשגר פקודת מערכת לבין‬
‫השימוש בכ"א מהפונקציות הללו הוא שהפונקציות מתאימות לכל מערכת‪-‬הפעלה‪ ,‬והשימוש ב‪ system() -‬מצריך יצירת‬
‫פקודה שונה לכל מערכת‪.‬‬

‫מודול ‪ os‬מכיל עוד פונקציות לשינוי שמות קבצים וספריות‪ ,‬פתיחת ‪-pipe‬ים בין תהליכים רצים‪ ,‬טיפול בקבצים (אלו הן‬
‫הפונקציות המובנות )(‪ close() ,open‬וכו'‪ ,‬והשימוש בהן לא מצריך ‪ import‬ל‪ ,)os-‬הרצת תוכניות‪ ,‬וכו'‪.‬‬
‫ספריית ‪sys‬‬
‫ספריית ‪ sys‬מכילה את כל הפונקציות שקשורות למערכת ה‪ Python-‬ולהרצת תוכנית ה‪ .Python-‬המודול כולל בתוכו‬
‫פונקציות לטיפול בקלט ופלט (לסוגיו השונים)‪ ,‬מידע על גירסת ה‪ ,Interpreter -‬משתנים שמשפיעים על התצוגה‪ ,‬מידע‬
‫על המודולים הטעונים‪ ,‬סדר הבתים (אינדיאניות)‪ ,‬גודל ה‪ ,int-‬ועוד‪.‬‬

‫כמה משתנים חשובים שיש במודול הם ‪ – version‬מכיל את גירסת ה‪ Interpreter -‬עליה מורצת התוכנית‪– platform ,‬‬
‫מכיל את סוג מערכת ההפעלה עליה רצה התוכנית (בניגוד ל‪ ,os.name -‬מכיל רק את סוג מערכת ההפעלה‪ ,‬למשל‬
‫‘‪ – path ,)’win32‬מכיל את כל הספריות בהן ייעשה חיפוש בעת טעינת מודולים‪ ,‬ו‪ – maxint-‬מכיל את גבול משתנה ה‪.int-‬‬

‫כמו כן‪ ,‬הספרייה מכילה שלושה משתנים – ‪ stdout ,stdin‬ו‪ .stderr -‬אלו הם אובייקטי הקבצים של הקלט הסטנדרטי‬
‫(לרוב המקלדת)‪ ,‬הפלט הסטנדרטי (לרוב המסך) ופלט השגיאות הסטנדרטי (המסך או קובץ)‪ .‬ניתן לכתוב ולקרוא‬
‫מקבצים אלה (כל קובץ וההרשאות שלו‪ ,‬כי ברור שאי‪-‬אפשר לקרוא מ‪ stdout -‬וכו') לשימושים מיוחדים‪ .‬הפונקציות ‪print‬‬
‫ו‪ raw_input-‬משתמשות באובייקטים אלה‪.‬‬

‫כאשר מריצים ‪-script‬ים מה‪ Command Line -‬ניתן לתת להם ארגומנטים‪ ,‬ממש כמו לכל תוכנית רגילה‪ .‬ב‪ C -‬לפונקציה‬
‫)(‪ main‬היו שני פרמטרים – ‪ argc‬ו‪ ,argv -‬בהם הועברו ארגומנטים אלה‪ .‬ב‪ Python-‬קיימת רשימה בשם ‪ argv‬בתוך ‪.sys‬‬
‫הרשימה מכילה את הארגומנטים‪ ,‬לפי הסדר בו הם הועברו‪ ,‬כאשר הארגומנט הראשון הוא לרוב שם הקובץ המורץ‪ .‬אם‬
‫ה‪ script-‬שרץ כרגע (או לצורך העניין ה‪ )Interpreter-‬לא הורץ משורת הפקודה‪ argv ,‬היא רשימה ריקה‪.‬‬

‫ספריית ‪string‬‬
‫ספרייה זו מכילה פונקציות לפעולות על מחרוזות‪ .‬בנוסף לפעולות שכבר מובנות בתוך השפה‪ ,‬ספרייה זו מספקת כלים‬
‫נוספים לעיבוד מחרוזות‪.‬‬

‫הפונקציות הפחות שימושיות בספרייה זו הן ‪ ,atoi ,atof‬ודומותיהן‪ ,‬משום שניתן לבצע את הפעולות שהן מבצעות ע"י‬
‫שימוש בפונקציות המובנות ‪ int‬ו‪ – float-‬שזה גם יותר נוח וגם יותר קריא‪.‬‬

‫קיימות בספרייה פונקציות לשינוי ה‪ Capitalization -‬של מחרוזות‪ ,‬כלומר כל נושא האותיות הקטנות והגדולות באנגלית‪.‬‬
‫הפונקציה ‪ capitalize‬מקבלת מחרוזת ומחזירה את אותה המחרוזת‪ ,‬כאשר האות הראשונה במילה הראשונה מתחילה‬
‫באות גדולהף והשאר קטנות‪.‬‬
‫‪ lower‬עושה אותו הדבר‪ ,‬רק‬ ‫הפונקציה ‪ upper‬מקבלת מחרוזת ומחזירה מחרוזת בה כל האותיות גדולות‪ .‬הפונקציה‬
‫מחזירה מחרוזת בה כל האותיות קטנות‪.‬‬

‫‪ lowercase‬מכילה את כל‬ ‫‪ uppercase‬מכילה את כל האותיות הגדולות‪.‬‬ ‫כמו כן‪ ,‬במודול קיימות הרשימות הבאות‪:‬‬
‫האותיות הקטנות‪ digits .‬מכילה את כל הספרות ( ‪ 0‬עד ‪ hexdigits .)9‬מכילה את כל הספרות בבסיס ‪ 0 ( 16‬עד ‪.)F‬‬
‫‪ octdigits‬מכילה את כל הספרות בבסיס ‪ 0( 8‬עד ‪ whitespace .)7‬מכילה את כל התווים שנחשבים כרווח (תו רווח‪ ,‬טאב‪,‬‬
‫מעבר שורה וכו')‪ punctuation .‬מכילה את כל תווי הניקוד‪.‬‬

‫עוד מספר פונקציות שימושיות הן ‪ index ,count ,join ,strip ,split‬ו‪:find-‬‬


‫‪ split‬מקבלת מחרוזת ותו‪ ,‬ומחזירה רשימה ובה האיברים מן המחרוזת שהופרדו בתו שהועבר לפונקציה‪ .‬דוגמה‪ :‬נעביר‬
‫לפונקציה מחרוזת ובה כמה שמות מופרדים בפסיקים‪:‬‬

‫”‪>>> names = “moshe,haim,yosi,danny,ludmila‬‬


‫)‟‪>>> string.split(names, „,‬‬
‫]‟‪[„moshe‟, „haim‟, „yosi‟, „danny‟, „ludmila‬‬

‫‪ strip‬מקבלת מחרוזת ומסירה ממנה את תווי ה‪ whitespace -‬שנמצאים בקצוות המחרוזת‪ .‬למשל‪ ,‬הנה המחרוזת הבאה‬
‫אחרי ‪:strip‬‬

‫‪>>> str = „ power rangers‬‬ ‫‪\t‬‬ ‫„‬


‫)‪>>> string.strip(str‬‬
‫‟‪„power rangers‬‬

‫‪ join‬מקבלת מחרוזת ורשימה ומחזירה מחרוזת שמורכבת מהאיברים ברשימה‪ ,‬כאשר בין כ"א מהם מצויה המחרוזת‬
‫הנתונה‪ .‬הפונקציה למעשה הפוכה ל‪:split-‬‬

‫]‟‪>>> u = [„moshe‟, „is‟, „not‟, „a‟, „kipod‬‬


‫)„ „ ‪>>> string.join(u,‬‬
‫‟‪„moshe is not a kipod‬‬

‫הפונקציה ‪ index‬מקבלת מחרוזת ותת‪-‬מחרוזת‪ ,‬ומחזירה את המקום הראשון בו תת‪-‬המחרוזת מופיעה בתוך המחרוזת‪.‬‬
‫‪ .)Exceptions‬הפונקציה ‪ find‬עושה בדיוק‬ ‫אם לא נמצא מקום כזה‪ ,‬הפונקציה זורקת שגיאה (יילמד בהמשך בפרק על‬
‫אותו הדבר‪ ,‬אבל אם היא לא מוצאת את תת‪-‬המחרוזת היא מחזירה ‪.-1‬‬

‫ספריית ‪math‬‬
‫ספרייה זו מכילה מספר פונקציות שימושיות וקבועים לשימושים מתמטיים‪ ,‬כמו חישובים עם ‪ ‬או ‪ ,℮‬או משחקים משונים‬
‫עם מספרי נקודה‪-‬עשרונית‪.‬‬
‫‪ pi‬ו‪ e-‬הם שני קבועים המייצגים את ‪ ‬ואת ‪ ℮‬בדיוק של ‪ 11‬ספרות אחרי הנקודה‪.‬‬

‫הפונקציה ‪ ceil‬מקבלת מספר עשרוני ומעגלת אותו כלפי מעלה‪ floor .‬מקבלת מספר ומעגלת אותו כלפי מטה (מקצצת‬
‫את החלק העשרוני)‪.‬‬

‫‪ acos ,asin‬ו‪ atan -‬הן הפונקציות‬ ‫הפונקציות ‪ cos ,sin‬ו‪ tan -‬הן כמובן שלוש הפונקציות הטריגונומטריות האהובות‪ ,‬ו‪-‬‬
‫ההופכיות להן‪.‬‬

‫שאר הפונקציות מ‪ math -‬די טריוויאליות‪ ,‬וניתן פשוט לרפרף עליהן ע"י הסתכלות במחרוזת התיעוד ( __‪ )__doc‬של כ"א‬
‫מהן‪.‬‬

You might also like