מבנה הנתונים האחרון והמעניין ביותר שאדבר עליו במדריך הזה נקרא מילון (Dictionary). למה מעניין? מילונים הם מבני הנתונים הגמישים ביותר בשפה והיחידים שמאפשרים לנו לייצג קשרים ואפילו היררכיות בנתונים שלנו.
מה זה מילון
כאמור, מילונים מאוד גמישים והמידע בהם מסודר בצורה של צמדים: מפתחות וערכים.
המבנה הלכאורה פשוט הזה מאפשר לנו לייצג קשרים בין פיסות מידע שונות וכך לייצר קונטקסט לנתונים שאנחנו מעוניינים לשמור. לצורך ההשוואה, רשימות הן בעצם רצפים של ערכים מבודדים ותלושים שאולי מייצגים משהו בעולם האמיתי (רשימת מחירים, שמות וכו') ואולי לא (רשימת תוצאות, נקודות על גרף, סדרה חשבונית של מספרים שמאפשרת לנו לבצע חישובים בלולאה). מילונים לעומת זאת מכילים מידע שהוא בדרך כלל משמעותי יותר כי יש לו קשר למידע אחר, ולכן אפשר להתייחס אליו כאל סוג של בסיס נתונים (database) בתוך פייתון. למעשה אנחנו יכולים לייצג מבני נתונים שלמים ומורכבים באמצעות מילון בודד ואכן יש סוגים רבים של בסיסי נתונים המתבססים על שיטת הצמדים הזאת.
מבנה של מילונים
אז איך נראים המילונים האלה? כמו שכתבתי, העיקרון עצמו פשוט מאוד אך אפשר לקחת אותו למקומות מורכבים. הבסיס לכל מילון הוא צמדים של מפתחות וערכים (לכל מפתח ערך אחד בלבד). מפתחות וערכים מופרדים ביניהם בנקודותיים ומהווים צמד אחד, הצמדים עצמם מופרדים בפסיקים וכל זה נמצא בתוך סוגריים מסולסלים (בדומה לסטים).
המונח "מפתח" הוא לא מקרי כאן והוא קיים גם בעולם בסיסי הנתונים כאשר "עמודת המפתח" מתייחסת לעמודה הראשית שמזהה את המידע בצורה ייחודית. אנו משתמשים במפתחות האלה כדי לזהות ולהתייחס לשורות ספציפיות בתוך בסיסי הנתונים.
גם במילונים, ממש כמו בטבלאות של בסיסי נתונים, על המפתחות להיות ייחודיים אך הערכים יכולים לחזור על עצמם.
מילונים מול רשימות
כל סוגי הרצפים שפגשנו עד עכשיו (מחרוזות, רשימות, טאפלים, סטים) הם בדיוק כפי שהמונח "רצפים" מרמז – קבוצה של ערכים, בדרך כלל מאותו הסוג ולפעמים גם מסודרים בסדר מסויים אך ללא קשר לערכים חיצוניים או בינם לבין עצמם. כל אחד מהם יכול להכיל עמודה מסוימת מתוך טבלה אך מילון יכול להכיל את הטבלה כולה.
אנסה להמחיש את הרעיון בעזרת טבלת גיבורי העל הבאה:
כמו שאמרתי רשימה או טאפל, יכולים להכיל עמודה אחת בלבד, למשל רשימה של שמות גיבורים, או מספרי הדמויות. הנה דוגמה למילון שמכיל את מספרי הגיבורים (מפתח) ושמותיהם (ערך):
אז בדוגמה הזאת כבר הכנסנו שתי עמודות לתוך מבנה נתונים יחיד. אבל למה לעצור כאן?
ייצוג טבלאות בתוך מילונים
מפתחות אמנם לא יכולים להכיל כל טיפוס נתונים שנרצה (עוד על זה בהמשך) אבל ערכים כן. לכן הערך שקשור למפתח מסוים יכול להיות מבנה נתונים בעצמו.
נראה מבלבל במבט ראשון אבל המבנה עצמו עדיין פשוט. כל צמד במילון מורכב בסך הכל ממפתח (מספר הגיבור) וערך שהוא במקרה הזה פרטי הגיבור מאורגנים בתוך רשימה. בדוגמה הזאת המילון heroes מכיל כבר את הטבלה בשלמותה.
בואו ניקח את זה שלב נוסף קדימה. אם אני לא מתמצא בקומיקס, ולא מכיר את הטבלה המקורית שעליה מבוסס המילון, יכול מאוד להיות שיהיה לי קשה להבין מה כל פרט ברשימה מייצג. בטבלה יש לנו שם לכל עמודה, מה שמאוד מקל על הבנת הנתונים. כדי "לייבא" את היתרון הזה למילון שלנו, אחליף את הרשימה במילון (כן, גם מילונים אפשר לקנן אחד בתוך השני…) כך שלכל פריט בתיאור הגיבורים יש "תווית", כלומר מפתח. זה כבר יראה ככה:
שוב, נראה הרבה יותר מסובך ממה שזה באמת. אנחנו עדיין מייצגים כל גיבור באמצעות המספר שלו ולכן המפתח נשאר זהה. הערך לעומת זאת השתנה מרשימה – שפשוט מכילה, ובכן, רשימה של פרטי הגיבור – למילון המכיל את פרטי הגיבור בצורה של צמדים – סוג הנתון (מפתח) והנתון עצמו (ערך). כאן אנחנו כבר ממש יכולים להתנהל מול המילון כבסיס נתונים לכל דבר. המבנה הזה כבר מאפשר לי, למשל, לבקש להציג את המין של גיבור מספר 7 (נקבה), את השם של גיבור מספר 5 (ג'וקר) או את השיוך של גיבור מספר 2 (רע).
האם אפשר לקחת את זה הלאה? בטח! למשל, אולי אני רוצה לכלול את מספרי חוברות הקומיקס שבהן מופיעה דמות מסוימת, או לאסוף על כל דמות רשימה של שמות הסרטים בהן השתתפה. במקרה כזה אפשר להוסיף למילון הפנימי מפתח בשם "Movies" כאשר הערך באותו צמד יהיה רשימה של שמות סרטים (קינון בדרגה שלישית). במקרה כזה הצמד הראשון (מפתח + ערך) יכול להיראות בערך ככה:
אין הגבלה אמיתית לרמת המורכבות שאתם יכולים ליצור ולמספר הקינונים וההיררכיות שנוכל לשלב במילון כזה, הכל תלוי במורכבות הנתונים שלכם ואיך שאתם רוצים לייצג אותם.
הפוסט הזה היה קצת יותר תיאורטי מהרגיל אז לא לדאוג עם הקונספט של מילונים עדיין לא יושב לכם כמו שצריך. בפוסט הבא נראה איך אפשר לעבוד עם מילונים, איך להכניס ואיך להוציא מהם מידע והנושא יהיה ברור יותר.
Comments