רשימות ב-Python

ב-Python יש סוג רשימה מובנה מעולה בשם "list". ליטרלים של רשימה נכתבים בתוך סוגריים מרובעים [ ]. הרשימות פועלות בדומה למחרוזות -- משתמשים בפונקציה len() ובסוגריים מרובעים [ ] כדי לגשת לנתונים, כשהרכיב הראשון מופיע באינדקס 0. (עיין במסמכי התיעוד הרשמיים של python.org).

  colors = ['red', 'blue', 'green']
  print(colors[0])    ## red
  print(colors[2])    ## green
  print(len(colors))  ## 3

רשימת מחרוזות 'אדום' 'כחול 'ירוק'

מטלה עם הסימן = ברשימות לא יוצרת עותק. במקום זאת, ההקצאה גורמת לכך ששני המשתנים מצביעים על רשימה אחת בזיכרון.

  b = colors   ## Does not copy the list

גם הצבעים וגם b מצביעים על הרשימה היחידה

"רשימה ריקה" היא פשוט זוג סוגריים ריקים [ ]. הסימן '+' פועל לצירוף שתי רשימות, כך ש-[1, 2] + [3, 4] ייתן [1, 2, 3, 4] (זה בדיוק כמו + עם מחרוזות).

'ל' ו-'IN'

המבנים *for* ו-*in* של Python הם שימושיים מאוד, והשימוש הראשון בהם מופיע באמצעות רשימות. מבנה *for* -- for var in list -- הוא דרך קלה להציג כל רכיב ברשימה (או באוסף אחר). אין להוסיף או להסיר מהרשימה במהלך האיטרציה.

  squares = [1, 4, 9, 16]
  sum = 0
  for num in squares:
    sum += num
  print(sum)  ## 30

אם אתם יודעים מה הסוג ברשימה, השתמשו בשם משתנה שמתעד את המידע, כמו num, name, או url. מאחר שלקוד Python אין תחביר אחר שמזכיר לך סוגים שונים, שמות המשתנים שלך הם דרך עיקרית למעקב אחר המתרחש. (זה קצת מטעה. ככל שתגדילו את החשיפה לפיתון, תראו אזכורים לרמזים לטיפוס, שמאפשרים להוסיף מידע הקלדה להגדרות הפונקציות. Python לא משתמש בהינטים מהסוג הזה כשהוא מפעיל את התוכנות. הן משמשות בתוכניות אחרות, כמו סביבות פיתוח משולבות (IDE) (סביבות פיתוח משולבות) וכלי ניתוח סטטיים, כמו לינטרים או בודקי סוגים, כדי לוודא שהפונקציות נקראות עם ארגומנטים תואמים).

המבנה *in* כשלעצמו מאפשר לבדוק בקלות אם רכיב מופיע ברשימה (או באוסף אחר) – value in collection – בודק אם הערך נמצא באוסף ומחזיר True/False.

  list = ['larry', 'curly', 'moe']
  if 'curly' in list:
    print('yay') ## yay

המבנים for/in משמשים לעיתים קרובות מאוד בקוד Python ועובדים על סוגי נתונים מלבד רשימה, כך שרצוי לזכור בעל-פה את התחביר שלהם. יכול להיות שיופיעו הרגלים משפות אחרות שבהם תתחילו לחזור באופן ידני על אוסף, וב-Python צריך להשתמש בו ל-/in.

אפשר גם להשתמש בפונקציות 'for/in' כדי לעבוד על מחרוזת. המחרוזת פועלת כרשימה של התווים שלה, כך ש-for ch in s: print(ch) מדפיס את כל התווים במחרוזת.

טווח

הפונקציה range(n) מחזירה את המספרים 0, 1, ... n-1 והטווח(a, b) מחזירה את a, a+1, ... b-1 - עד המספר האחרון, אך לא כולל. השילוב של הפונקציה for-loop והפונקציה range() מאפשר ליצור לולאת <for> מספרית מסורתית:

  ## print the numbers from 0 through 99
  for i in range(100):
    print(i)

יש וריאנט xrange() שחוסך את העלות של בניית הרשימה המלאה למקרים שרגישים לביצועים (ב-Python 3, ההתנהגות של range() תהיה טובה וכדאי לשכוח מ-xrange() ).

בזמן לולאה

ב-Python יש גם את לולאת הזמן הרגילה, והצהרות *break* ו-*continue* פועלות כמו ב-C++ ו-Java, ומשנות את מהלך הלולאה הפנימית ביותר. לולאות ה-for/in שלמעלה פותרות את המקרה הנפוץ של חזרה על כל רכיב ברשימה, אבל לולאת בזמן נותנת לך שליטה מלאה על מספרי האינדקסים. הנה לולאת זמן שניגשת לכל רכיב שלישי ברשימה:

  ## Access every 3rd element in a list
  i = 0
  while i < len(a):
    print(a[i])
    i = i + 3

הצגת רשימה של שיטות

הנה כמה שיטות נפוצות נוספות ליצירת רשימות.

  • list.append(elem) -- מוסיף רכיב יחיד לסוף הרשימה. שגיאה נפוצה: לא מחזירה את הרשימה החדשה, אלא רק משנה את המקור.
  • list.insert(index, elem) -- מוסיף את הרכיב באינדקס הנתון ומעביר את הרכיבים ימינה.
  • list.extend(list2) מוסיף את הרכיבים ב-list2 לסוף הרשימה. השימוש + או += ברשימה דומה לשימוש ב-extension().
  • list.index(elem) -- מחפש את הרכיב הנתון מתחילת הרשימה ומחזיר את האינדקס שלו. פקודה של ValueError אם הרכיב לא מופיע (יש להשתמש ב-'in' כדי לבדוק בלי ValueError).
  • list.remove(elem) -- מחפש את המופע הראשון של הרכיב הנתון ומסיר אותו (זורק את ValueError אם הוא לא קיים)
  • list.sort() -- ממיין את הרשימה במקום (לא מחזיר אותה). (הפונקציה ממוין (()) שמוצגת מאוחר יותר היא המועדפת.)
  • list.reverse() -- הופכת את הרשימה למקומה (לא מחזירה אותה)
  • list.pop(index) -- מסיר ומחזיר את הרכיב באינדקס הנתון. מחזירה את הרכיב השמאלי ביותר אם האינדקס מושמט (בערך ההיפך מ-addend() ).

שימו לב שאלה *שיטות* באובייקט רשימה, ואילו len() היא פונקציה שלוקחת את הרשימה (או מחרוזת, או כל דבר אחר) כארגומנט.

  list = ['larry', 'curly', 'moe']
  list.append('shemp')         ## append elem at end
  list.insert(0, 'xxx')        ## insert elem at index 0
  list.extend(['yyy', 'zzz'])  ## add list of elems at end
  print(list)  ## ['xxx', 'larry', 'curly', 'moe', 'shemp', 'yyy', 'zzz']
  print(list.index('curly'))    ## 2

  list.remove('curly')         ## search and remove that element
  list.pop(1)                  ## removes and returns 'larry'
  print(list)  ## ['xxx', 'moe', 'shemp', 'yyy', 'zzz']

שגיאה נפוצה: שימו לב שהשיטות שלמעלה לא *מחזירות* את הרשימה ששונתה, אלא רק משנות את הרשימה המקורית.

  list = [1, 2, 3]
  print(list.append(4))   ## NO, does not work, append() returns None
  ## Correct pattern:
  list.append(4)
  print(list)  ## [1, 2, 3, 4]

פיתוח רשימה

דפוס נפוץ אחד הוא להתחיל רשימה כרשימה הריקה [], ולאחר מכן להשתמש ב-append() או ב-expand() כדי להוסיף לה רכיבים:

  list = []          ## Start as the empty list
  list.append('a')   ## Use append() to add elements
  list.append('b')

הצגת רשימה של פלחים

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

  list = ['a', 'b', 'c', 'd']
  print(list[1:-1])   ## ['b', 'c']
  list[0:2] = 'z'    ## replace ['a', 'b'] with ['z']
  print(list)         ## ['z', 'c', 'd']

תרגיל: list1.py

כדי לתרגל את החומר בקטע הזה, נסה את הבעיות ב-list1.py שאינן משתמשות במיון (בתרגילים הבסיסיים).