פוסט
רשימות ב-Python
רשימה מחזיקה הרבה ערכים לפי סדר. יצירה, אינדקסים וחיתוך, הוספה והסרה, מיון, העתקה בלי הפתעות, ומילה על tuples.
תוכניות אמיתיות עובדות עם הרבה ערכים בבת אחת: המוצרים בעגלת קניות, השורות בקובץ, הציונים של כיתה. הכלי הבסיסי לזה הוא הרשימה (list). התיעוד מגדיר אותה כגמישה ביותר מבין טיפוסי הנתונים המורכבים של Python: רצף ערכים בתוך סוגריים מרובעים, בסדר קבוע, שאפשר לשנות.
כל דוגמה כאן הורצה עם Python 3.13. ההתנהגות נבדקה מול החלק על רשימות במדריך הרשמי, עוד על רשימות והתיעוד של הטיפוס list.
יצירת רשימה
כותבים את הערכים בין סוגריים מרובעים, מופרדים בפסיקים:
fruits = ["apple", "banana", "cherry"]
scores = [90, 72, 85]
empty = []
mixed = ["Dana", 30, True]
print(fruits, len(fruits))
print(empty, len(empty))
print(type(scores))
['apple', 'banana', 'cherry'] 3
[] 0
<class 'list'>
רשימה יכולה להחזיק ערכים מטיפוסים שונים, כמו mixed, אבל בדרך כלל כל הפריטים מאותו טיפוס. len() נותן את מספר הפריטים, בדיוק כמו במחרוזת.
list() בונה רשימה מכל דבר שאפשר לעבור עליו פריט אחרי פריט, כמו מחרוזת (פוסט על המרת טיפוסים) או range (פוסט על לולאות).
אינדקסים וחיתוך
ברשימות משתמשים באותם אינדקסים כמו במחרוזות: הפריט הראשון הוא 0, ואינדקסים שליליים סופרים מהסוף. חיתוך [start:stop] מחזיר רשימה חדשה:
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[0], fruits[-1])
print(fruits[1:3])
print(fruits[::-1])
apple date
['banana', 'cherry']
['date', 'cherry', 'banana', 'apple']
אינדקס שעובר את הסוף הוא שגיאה, אבל חיתוך שעובר את הסוף מחזיר את מה שקיים:
print(fruits[1:100])
print(fruits[10])
['banana', 'cherry', 'date']
IndexError: list index out of range
שינוי רשימה
כאן רשימות שונות ממחרוזות. מחרוזת אי אפשר לשנות, ורשימה אפשר. המדריך הרשמי מנסח את זה כך: “Unlike strings, which are immutable, lists are a mutable type”. אפשר להחליף פריט במקום:
scores = [90, 72, 85]
scores[1] = 75
print(scores)
[90, 75, 85]
כדי להוסיף פריטים משתמשים במתודות. append() מוסיף פריט אחד לסוף, insert() מוסיף פריט במיקום מסוים, ו-extend() מוסיף את כל הפריטים של רשימה אחרת:
cart = ["milk"]
cart.append("bread")
cart.insert(0, "eggs")
cart.extend(["tea", "rice"])
print(cart)
['eggs', 'milk', 'bread', 'tea', 'rice']
כדי להסיר פריטים: remove() מוחק את הפריט הראשון עם ערך מסוים, pop() מוחק לפי מיקום ומחזיר את הפריט, ו-del מוחק לפי אינדקס או חיתוך:
cart.remove("milk")
last = cart.pop()
first = cart.pop(0)
print(cart, last, first)
del cart[0]
print(cart)
['bread', 'tea'] rice eggs
['tea']
pop() בלי ארגומנט לוקח מהסוף. זה הופך רשימה למחסנית (stack) טבעית: append() כדי לדחוף, ו-pop() כדי לקחת בחזרה את הפריט האחרון.
חיפוש וספירה
in בודק אם ערך נמצא ברשימה ומחזיר True או False. index() נותן את המיקום של ההתאמה הראשונה, ו-count() סופר התאמות:
colors = ["red", "green", "blue", "green"]
print("green" in colors, "pink" in colors)
print(colors.index("green"), colors.count("green"))
True False
1 2
index() מעלה שגיאה כשהערך לא קיים, אז בודקים קודם עם in, או משתמשים בתנאים מהפוסט הבא:
print(colors.index("pink"))
ValueError: 'pink' is not in list
ברשימות של מספרים, sum(), min() ו-max() עושים את מה שהשם שלהם אומר:
scores = [90, 72, 85]
print(sum(scores), min(scores), max(scores))
print(sum(scores) / len(scores))
247 72 90
82.33333333333333
מיון
יש שתי דרכים למיין. המתודה sort() ממיינת את הרשימה עצמה ומחזירה None. הפונקציה sorted() לא נוגעת ברשימה ומחזירה רשימה חדשה וממוינת:
numbers = [3, 1, 2]
print(sorted(numbers), numbers)
numbers.sort()
print(numbers)
numbers.sort(reverse=True)
print(numbers)
[1, 2, 3] [3, 1, 2]
[1, 2, 3]
[3, 2, 1]
הארגומנט key ממיין לפי משהו שמחושב מכל פריט. key=len ממיין מילים לפי אורך, ו-key=str.lower מתעלם מאותיות גדולות וקטנות:
words = ["banana", "Apple", "fig"]
print(sorted(words))
print(sorted(words, key=str.lower))
print(sorted(words, key=len))
['Apple', 'banana', 'fig']
['Apple', 'banana', 'fig']
['fig', 'Apple', 'banana']
sorted(words) רגיל שם את "Apple" ראשון כי אותיות גדולות באות לפני קטנות, וזה כמעט אף פעם לא מה שרוצים כשממיינים שמות.
שני שמות, רשימה אחת
השמה של רשימה למשתנה אחר לא מעתיקה אותה. שני השמות מצביעים על אותה רשימה, אז שינוי דרך שם אחד נראה גם דרך השני:
a = [1, 2, 3]
b = a
b.append(4)
print(a)
print(a is b)
[1, 2, 3, 4]
True
כדי לקבל רשימה נפרדת, מעתיקים עם copy(), list() או חיתוך מלא [:]:
a = [1, 2, 3]
c = a.copy()
c.append(4)
print(a, c)
[1, 2, 3] [1, 2, 3, 4]
אלה העתקות רדודות (shallow): רשימה שנמצאת בתוך הרשימה עדיין משותפת. ברשימות של מספרים ומחרוזות זה אף פעם לא משנה.
Tuples: רשימה שאי אפשר לשנות
tuple נכתב עם סוגריים עגולים במקום מרובעים. ניגשים אליו עם אינדקסים כמו לרשימה, אבל אי אפשר לשנות אותו אחרי שנוצר:
point = (3, 4)
print(point[0], len(point))
x, y = point
print(x, y)
point[0] = 10
3 2
3 4
TypeError: 'tuple' object does not support item assignment
x, y = point הוא פירוק (unpacking): שם אחד לכל פריט, כמו ב-x, y = 1, 2 מהפוסט על משתנים. משתמשים ב-tuple לקבוצה קבועה של ערכים ששייכים יחד, כמו קואורדינטות, וברשימה לאוסף שגדל וקטן.
טעויות נפוצות
- שימוש בתוצאה של
sort(). numbers = numbers.sort()שם ב-numbersאתNone. כותביםnumbers.sort()לבד, אוnumbers = sorted(numbers). -
append()עם רשימה. cart.append(["tea", "rice"])מוסיף פריט אחד, רשימה בתוך הרשימה. כדי להוסיף כל פריט בנפרד משתמשים ב-extend(). - טעות של אחד באינדקס. הפריט האחרון הוא
items[len(items) - 1], או פשוטitems[-1]. items[len(items)]הואIndexError. - משתנה בשם
list. list = [1, 2]מסתיר אתlist()המובנה (הסתרת שם מובנה).
מה הלאה
בפוסט הבא: תנאים עם if, elif ו-else, שמחליטים מה להריץ לפי ערכים כמו "green" in colors.