שיעור זה שונה. אין "בואו ונלמד תכנות". יש כאן מטרה אחת: להפוך אותך לאדם שיכול לכתוב Python עובד, קריא ומהיר — כי ב-5 שיעורים הבאים תבנה ממשה אמיתי, ובגאמא תבחן על Python ישירות.
✓נושאי השיעור
משתנים וטיפוסים — int, float, str, bool, None, Type Casting
מחרוזות — Indexing, Slicing, מתודות, f-strings
תנאים — if/elif/else, Truthy/Falsy, Ternary
לולאות — for, while, break, continue, enumerate, nested
a, b = 17, 5
print(a + b) # 22 — חיבור
print(a // b) # 3 — חילוק שלם (Floor Division)
print(a % b) # 2 — מודולו — שארית חלוקה ← חשוב!
print(a ** b) # 1419857 — חזקה (17^5)
print(a / b) # 3.4 — חילוק (תמיד float!)
# מודולו — שימוש נפוץ:
10 % 2 == 0 # True → מספר זוגי
i % 7 == 0 # True → כל שבוע
i % n # תמיד ערך בין 0 ל-n-1
s[0:3] מחזיר אינדקסים 0, 1, 2 — אבל לא 3! זה עקבי ב-Python: range(0,3) גם לא כולל 3. שאלה קלה: אם s="GAMMA", מה s[-3:-1]? → "MM" (אינדקסים 2,3 — לא כולל -1).
✏תרגול עצמי3 שאלות
שאלה ב׳.3
מה יחזיר: "Python"[1:4]?
✓ תשובה: ג) yth — אינדקסים 1,2,3: y, t, h. stop=4 לא נכלל.
✓ תשובה: ב) — f"שם: {name}, גיל: {age}". מ-Python 3.6+. הדרך המומלצת — מטפל בהמרה אוטומטית. גם ביטויים: f"סכום: {a+b}".
🎯 דגש למבחן
מחרוזות ב-Python הן Immutable. אי אפשר לשנות תו במקום: s[0] = "J" זורק TypeError. כל "שינוי" (replace, upper, +) יוצר אובייקט חדש בזיכרון. לכן שרשור בלולאה (s += x) הוא O(n²) — בונה מחרוזת חדשה בכל סיבוב; הדרך הנכונה היא לאסוף לרשימה ולסיים ב-"".join(parts). הצד החיובי: בגלל האי-שינויות מחרוזות ניתנות ל-Hash ולכן יכולות לשמש כמפתחות ב-Dict וכאיברים ב-Set.
// פרק 3
תנאים ולולאות
תנאים מאפשרים לתוכנית לקבל החלטות. לולאות מאפשרות חזרה על קוד. אלו הכלים הבסיסיים של כל לוגיקה.
if / elif / else + Truthy/Falsy
score = 75
if score >= 90: print("מצוין!")
elif score >= 80: print("טוב מאוד")
elif score >= 70: print("טוב") # ← יודפס
else: print("כישלון")
# Truthy/Falsy — Python בודק כל ערך כתנאי:
users = []
if users: print("יש משתמשים")
else: print("אין משתמשים") # ← רשימה ריקה = Falsy
# Ternary expression:
result = "גדול" if x > 5 else "קטן"
for ו-while
# for עם range()
for i in range(5): print(i) # 0,1,2,3,4
for i in range(2, 7): print(i) # 2,3,4,5,6
for i in range(0,10,2): print(i) # 0,2,4,6,8
for i in range(5,0,-1): print(i) # 5,4,3,2,1
# for על רצף:
for char in "Python": print(char) # P,y,t,h,o,n
# enumerate — מספר + ערך:
for i, fruit in enumerate(["תפוח","בננה","תפוז"]):
print(f"{i}: {fruit}") # 0: תפוח, 1: בננה...
# break ו-continue:
for i in range(10):
if i == 5: break # יצא — 0,1,2,3,4
for i in range(10):
if i%2==0: continue # דלג זוגיים — 1,3,5,7,9
✓ תשובה: ג) — a=[1,2]; b=[1,2]; a==b → True (ערכים זהים); a is b → False (אובייקטים שונים). תמיד השתמש ב-== לערכים, is רק ל-None/True/False.
// פרק 4
Lists ו-List Comprehensions
List היא אוסף מסודר ו-Mutable של פריטים מכל טיפוס. List Comprehension — יצירת רשימה בשורה אחת — הוא אחד הדברים שהופכים Python לאלגנטית.
מתודות חשובות
fruits = ["תפוח", "בננה", "תפוז"]
fruits.append("ענב") # הוסף בסוף
fruits.insert(1, "מנגו") # הוסף במיקום
fruits.remove("בננה") # הסר לפי ערך
last = fruits.pop() # הסר ומחזיר אחרון
nums = [3, 1, 4, 1, 5, 9, 2]
nums.sort() # ממיין in-place
nums.sort(reverse=True) # יורד
sorted_new = sorted(nums) # מחזיר חדש, מקורי לא משתנה!
print(nums.count(1)) # כמה פעמים 1 מופיע
# חיבור:
a + b # רשימה חדשה
a.extend(b) # מוסיף לa in-place
List Comprehension
# בלי comprehension — 4 שורות:
squares = []
for x in range(10):
squares.append(x**2)
# עם comprehension — שורה אחת:
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# עם תנאי (filter):
evens = [x for x in range(20) if x % 2 == 0]
# מבנה: [ביטוי for משתנה in איטרבל if תנאי]
# דוגמה מעשית:
students = [{"name":"Alice","score":92},{"name":"Bob","score":58}]
passed = [s["name"] for s in students if s["score"] >= 60]
# ['Alice']
Dict = מפתח-ערך. Tuple = רשימה Immutable. Set = ייחודי, ללא סדר. ביחד עם List — אלה 4 מבני הנתונים הבסיסיים של Python.
Dictionary
phone_book = {"Alice": "050-123", "Bob": "052-456"}
# גישה
print(phone_book["Alice"]) # "050-123"
print(phone_book.get("Dan", "N/A")) # "N/A" — לא שגיאה!
# שינוי
phone_book["Alice"] = "050-000" # עדכון
phone_book["Dan"] = "058-789" # הוספה
del phone_book["Bob"] # מחיקה
# איטרציה — items() הכי שימושי:
for name, phone in phone_book.items():
print(f"{name}: {phone}")
# Dict Comprehension:
squares = {x: x**2 for x in range(5)}
# {0:0, 1:1, 2:4, 3:9, 4:16}
הרחבה Tuples, Sets ו-השוואה מלאה ›
# Tuple — Immutable, Ordered
coords = (3, 7)
x, y = coords # Unpacking!
# coords[0] = 10 # TypeError!
single = (42,) # שים לב לפסיק!
# Set — Unique, Unordered
colors = {"אדום", "ירוק", "אדום"} # כפילויות מוסרות!
print(colors) # {'ירוק', 'אדום'} (סדר לא מובטח)
empty = set() # {} = dict ריק, לא set!
print("אדום" in colors) # True — O(1) בדיקה!
# פעולות קבוצה:
a = {1,2,3,4,5}; b = {4,5,6,7,8}
print(a | b) # איחוד: {1,2,3,4,5,6,7,8}
print(a & b) # חיתוך: {4,5}
print(a - b) # הפרש: {1,2,3}
# הסרת כפילויות מlist:
list(set([1,2,2,3,3,3])) # [1,2,3]
מבנה
Mutable?
סדר?
כפילויות?
סינטקס
List
✅
✅
✅
[1,2,3]
Tuple
❌
✅
✅
(1,2,3)
Set
✅
❌
❌
{1,2,3}
Dict
✅
✅ (3.7+)
מפתחות ❌
{"a":1}
✏תרגול עצמי4 שאלות
שאלה ב׳.6
d = {"a":1, "b":2}; print(d.get("c", 99))
✓ תשובה: ד) 99 — .get(key, default) = מחזיר default אם המפתח לא קיים. d["c"] היה זורק KeyError!
שאלה ב׳.10
t = (1,2,3); t[0] = 99 — מה קורה?
✓ תשובה: ב) TypeError — Tuple = Immutable. לא ניתן לשנות אחרי יצירה. זו נקודת המפתח של Tuple.
Dry Run — Dict
words = ["apple","banana","cherry","date","elderberry"]
result = {}
for word in words:
length = len(word)
if length not in result:
result[length] = []
result[length].append(word)
print(result)מה הפלט?
✓ תשובה: ב) — apple(5), banana(6), cherry(6)→קיים!, date(4), elderberry(10). מקבצת מילים לפי אורכן.
ד׳1 — ניתוח פונקציה
def mystery(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
print(mystery([3,1,4,1,5,9,2,6,5,3,5]))מה עושה הפונקציה?
✓ תשובה: ב) [3,1,4,5,9,2,6] — set לבדיקת O(1) "האם ראינו?". list לשמירת סדר ראשון הופעה. הסרת כפילויות בסדר.
🎯 דגש למבחן
Set מול List — הבדל ביצועים, לא סגנון.Set ו-Dict בנויים על Hash Table: מחשבים hash(x) וקופצים ישירות לתא, ולכן בדיקת x in s היא O(1) בממוצע. List נסרקת רצוף איבר-איבר, ולכן x in lst היא O(n). על מיליון איברים ההפרש הוא בין מיקרו-שניות לשניות. המחיר: Set לא שומר סדר מקורי, דורש איברים Hashable (ולכן לא רשימות) וצורך יותר זיכרון.
// פרק 6
Mutability: מה שמשתנה ומה שלא
Mutability הוא אחד הרעיונות הכי חשובים ב-Python, ואחד הגורמים הנפוצים ביותר לבאגים. הבנתו תמנע ממך שעות debugging.
טיפוס
Mutable?
הסבר
int, float, bool, str, tuple
Immutable ❌
לא ניתן לשנות — פעולה יוצרת אובייקט חדש
list, dict, set
Mutable ✅
ניתן לשנות in-place
References — שני שמות לאותה קוביה
# Immutable — בטוח:
a = 5; b = a; b = 10
print(a) # 5 ← a לא השתנה!
# Mutable — זהירות!
list_a = [1, 2, 3]
list_b = list_a # שניהם מצביעים לאותה list!
list_b.append(4)
print(list_a) # [1, 2, 3, 4] ← list_a גם השתנה!
# פתרון — עותק:
copy1 = original.copy() # Shallow Copy
copy2 = original[:] # גם Shallow Copy
✓ תשובה: ג) [1,2,3,4] — x = a לא מעתיק! שניהם מצביעים לאותה list. x.append(4) משנה אותה. a גם רואה שינוי.
שאלה Mutability נוספת
x = [1,2,3]; y = x; y += [4,5]; print(x)
✓ תשובה: ד) [1,2,3,4,5] — y += [4,5] שקול ל-y.extend([4,5]) שמשנה in-place. x גם רואה שינוי כי שניהם מצביעים לאותה list!
Dry Run — is vs ==
a = [1,2,3]
b = [1,2,3]
c = a
print(a == b, a is b)
print(a == c, a is c)מה הפלט?
✓ תשובה: ב) True False / True True — a==b: ערכים זהים → True. a is b: אובייקטים שונים → False. a==c: זהים → True. a is c: אותו אובייקט! (c=a) → True.
// פרק 7
פונקציות מובנות + שאלת גאמא
Python מגיעה עם עשרות פונקציות מובנות שמזרזות עבודה. הנה הכי חשובות, ולסיום — שאלה בסגנון גאמא אמיתי.
nums = [3, 1, 4, 1, 5, 9, 2, 6]
print(len(nums)) # 8
print(min(nums)) # 1
print(max(nums)) # 9
print(sum(nums)) # 31
print(sorted(nums)) # [1,1,2,3,4,5,6,9]
# isinstance:
isinstance(3, int) # True
isinstance(3, (int, float)) # True — אחד מהם
# all, any — שימושי לבדיקת תנאים:
grades = [80, 90, 75, 85]
all(g >= 60 for g in grades) # True — כולם עברו
any(g >= 90 for g in grades) # True — יש אחד >=90
# enumerate ו-zip:
for i, val in enumerate(["א","ב","ג"], start=1):
print(f"{i}. {val}") # 1. א, 2. ב, 3. ג
names = ["Alice","Bob"]; scores = [95,82]
for name, score in zip(names, scores):
print(f"{name}: {score}")
הרחבה שאלת גאמא — ניתוח קוד מלא ›
def analyze(data):
result = {}
for item in data:
key = item[0] # אות ראשונה
val = item[1] # המספר
if key in result:
result[key].append(val)
else:
result[key] = [val]
return result
data = [("a",1),("b",2),("a",3),("c",4),("b",5),("a",6)]
output = analyze(data)
print(output)
matrix = [[1,2,3],[4,5,6],[7,8,9]]
target = 5
found = False
for i, row in enumerate(matrix):
for j, val in enumerate(row):
if val == target:
found = True
break
if found: break
print(f"({i},{j})" if found else "not found")מה הפלט?
def f(n):
if n == 0: return 0
if n == 1: return 1
return f(n-1) + f(n-2)
print([f(i) for i in range(7)])מה הפלט?
✓ תשובה: ב) [0,1,1,2,3,5,8] — זוהי סדרת פיבונאצ'י! f(0)=0, f(1)=1, f(2)=1, f(3)=2, f(4)=3, f(5)=5, f(6)=8. range(7) = 0 עד 6.
🎯 דגש למבחן
Default arguments מוערכים פעם אחת בלבד — ברגע הגדרת הפונקציה (כשה-def מתבצע), לא בכל קריאה. ערך ברירת המחדל נשמר באובייקט הפונקציה עצמו (func.__defaults__). לכן ערך ברירת מחדל Mutable הוא מלכודת קלאסית: def add(x, lst=[]) — כל הקריאות חולקות אותה רשימה, והיא מצטברת בין קריאה לקריאה. הפתרון המקובל: def add(x, lst=None) ובתוך הגוף if lst is None: lst = [].
// אתגר מעשי
אתגר מעשי — Python — מחרוזות ואוספים
שיא השיעור: לבנות, לתקן ולנתח — לא לזהות תשובה. פתרו את משימת החובה ואז את האתגר שמעליה; ההגשה נבדקת אוטומטית מול מקרי-קצה נסתרים (וחלקן אוכפות יעילות דרך גודל-קלט).
T1 · מתחיל150 נק'~10 דק'debug
תיקון באג — בודק פלינדרום
בודק הפלינדרום הבא מתעלם מרישיות אך שבור: הוא מדלג על השוואת התו הראשון לאחרון, ולכן מחרוזת שנבדלת רק בקצוות מסווגת כפלינדרום בטעות (למשל "yabax" מוחזר True). מצא ותקן. החזר את הגרסה המתוקנת.
// הקוד השבור לתיקון
def is_palindrome(s: str) -> bool:
s = s.lower()
n = len(s)
for i in range(1, n // 2): # באג כאן
if s[i] != s[n - i - 1]:
return False
return True
דוגמאות
is_palindrome('racecar')→True
is_palindrome('yabax')→False
is_palindrome('Anna')→True
הפתרון נשמר מקומית ומשותף עם עמוד „כתיבת קוד”.
פתרון-ייחוס תיקון באג — בודק פלינדרום ›
def is_palindrome(s: str) -> bool:
s = s.lower()
n = len(s)
for i in range(n // 2): # התיקון: מ-0 (הגרסה השבורה דילגה על התו הראשון)
if s[i] != s[n - i - 1]:
return False
return True
T2 · בסיסי200 נק'~15 דק'algorithmic
התו היחיד הראשון
נתונה מחרוזת s. החזר את האינדקס של התו הראשון שאינו חוזר על עצמו במחרוזת. אם אין תו כזה — החזר -1. חובה O(n): קלט של מיליון תווים חייב לרוץ בזמן. (פתרון תמים שסופר מופעים עם s.count בתוך לולאה הוא O(n²) וייפסל ב-timeout.)
דוגמאות
first_uniq('leetcode')→0
first_uniq('loveleetcode')→2
first_uniq('aabb')→-1
הפתרון נשמר מקומית ומשותף עם עמוד „כתיבת קוד”.
פתרון-ייחוס התו היחיד הראשון ›
from collections import Counter
def first_uniq(s: str) -> int:
c = Counter(s) # ספירה אחת: O(n)
for i, ch in enumerate(s):
if c[ch] == 1:
return i
return -1
שאלות תרגול ותשובות (8)
שאלה 1 · מה יודפס בקוד הבא?
x = 10
y = 3
print(x // y, x % y)
א. 3.33 1
ב. 3 1
ג. 3 0.33
ד. 4 1
תשובה: ב
// היא חלוקה שלמה (10//3 = 3) ו-% מחזיר את השארית (10-9 = 1).
שאלה 2 · איזה מהערכים הבאים הוא Falsy ב-Python?
א. "False"
ב. [0]
ג. 0.0
ד. (1,)
תשובה: ג
Falsy: False, None, 0, 0.0, "", [], {}, set(). מחרוזת או אוסף לא ריקים הם תמיד Truthy.