6 min. read

פרק קודם:

פייתון 10 - מיזוג רשימות

מה נלמד

  • Named Tuples
  • Counter
  • ChainMap
  • Deque

הקדמה

לפייתון יש כמה יכולות נוספות מתחת לשרוול שייעזרו בביצוע משימות פשוטות.

Named Tuples

אם אתם לא וזכרים מה זה טאפל:

פייתון 9 - מילונים, טופלים וסטים

Named tuple מוסיף שמות לערכי הטאפל כך שאנחנו יכולים לגשת בעזרת שם לערך מסוים.

1
2
3
4
5
6
7
from collections import namedtuple

Person = namedtuple('Person', ['Name','Age'])

p = Person(Name='Bob', Age = 42)

print(p)

פרמטרים לפונקציה namedtuple:

1
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None
  • typename - שם הטאפל, בעזרתו ניצור טאפלים חדשים

  • field_named - רשימה של הפרמטרים.
    ניתן להעביר רשימה, או מחרוזת עם שמות, השמות יכולים להיות מופרדים ברווח או פסיקים:

    1
    2
    3
    Person = namedtuple('Person', ['Name','Age'])
    Person2 = namedtuple('Person2', 'Name Age')
    Person3 = namedtuple('Person3', 'Name,Age')
  • rename - מוודא שהשמות של המשתנים נכונים לפי שפת פייתון.
    למשל אסור להתחיל משתנה עם מספר,
    או אסור ששם משתנה יהיה מילה שמורה בפייתון.
    במידה ושם המשתנה לא תקין הפונקציה תחליף אותו לקו תחתון ומספר.

1
2
3
4
5
Person = namedtuple('Person',['Age','def'], rename=True)
p = Person(12,12)
print(p)

# prints Person(Age=12, _1=12)
  • defaults - רשימה של ערכים בברירת מחדל כאשר יוצרים טאפל ריק.
  • module - מחליף את הפרמטר __module__ במידה ומועבר הפרמטר.
    מודולים ניתן ללמוד בפרק 14: פייתון 14 - מודולים

גישה למשתנים

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

1
2
3
4
p = Person(Name='Bob', Age = 42)

name = p[0]
age = p[1]

ניתן לפצל טאפל למשתנים:

1
2
3
4
p = Person(Name='Bob', Age = 42)

name,age = p
print(f'Hello {name}, your calculated age is {age}')

פיצול טאפלים הוא קונספט נפוץ בתכנות וקיים גם בשפות אחרות - קונספט זה נקרא Deconstruction.
לא להתבלבל עם ה-Dtor או ה-Destructor האחראי על מחיקה של מידע.
בפייתון זה לא נפוץ ולכן אין צורך להשתמש בזה כל כך.

ניתן לגשת למשתנים על פי שם:

1
2
3
4
p = Person(Name='Bob', Age = 42)

print(p.Name)
print(p.Age)

תרגילים

  1. שלחו לנו קטע קוד, אך בגלל באג קיבלנו רק את חלקו!
    עזרו להשלים את החסר:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from collections import ______
import math

data = [0, 1, 1, 2]

Point = ______


def Distance(point1, point2):
part1 = ((point2.X - point1.X)**2)
part2 = ((point2.Y - point1.Y) ** 2)
inner = part1 + part2
return math.sqrt(inner)

pointLength = 2
totalPoints = len(data)/pointLength

points = []
for i in range(totalPoints):
x = data[i * pointLength]
y = data[i * pointLength + 1]
point = ____
points.____(point)

distance = Distance(points[0], points[1])
print(f'Distance is {distance}')

Counter

Counter הוא אובייקט פשוט - ניתן לייחס אותו לרשימה של מילים עם מספרים.
כל מטרתו הוא לעזור לספור כמות של כל דבר שאנו רוצים.
מאחורי הקלעים Counter הוא מילון.

1
2
3
4
from collections import Counter

productCounter = Counter(milk=1000, eggs=2500, flour=5000)
print(productCounter)

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

1
2
countChars = Counter('abcbfbccfaabcafbcabcfabcabc').most_common(3)
print(countChars)

פונקציות שימושיות

  • most_common(n) - יחזיר את המופעים הנפוצים ביותר.
  • elements - יחזיר את כל המופעים כאלמנטים בודדים.
    למשל אם יש לנו 8 פעמים a הוא יוצג כ8 מופעים שונים של התו:
1
2
3
4
everything = Counter('abcbfbccfaabcafbcabcfabcabc').elements()
print(sorted(everything))

# prints ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'f', 'f', 'f', 'f']
  • total - מחזיר את כמות כל האלמנטים.
  • פעולות חיבור, חיסור ומיזוג:
1
2
3
4
from collections import Counter

productsA = Counter(eggs=3, milk=1)
productsB = Counter(eggs=1, milk=2)

חיבור וחיסור:

1
2
productsA + productsB
productsA - productsB

מיזוג:

1
productsA & productsB

איחוד:

1
productsA | productsB

השוואה:

1
productsA == productsB

בדיקת הכלה:

1
productsA <= productsB

תרגיל

  1. כתבו תכנית שסופרת פריטים אשר המשתמש רושם.
    כאשר המשתמש רשם “end” על התכנית לסכם את הכל ולהציג את הפריטים ואת כמותם.
    תכנית הרצה לדוגמא:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    milk
    milk
    eggs
    flour
    end
    ----------------------
    milk : 2
    eggs : 1
    flour : 1
    ----------------------

ChainMap

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

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

פייתון 10.2 - אובייקטי רשימות ויכולות
1
2
3
4
5
6
7
dictOne = {'a':2, 'b': 3,'d':6 }

dictTwo = {'a':5, 'b': 1, 'c':2 }

dictOne.update(dictTwo)

print(dictOne)

לחילופין, נוכל להשתמש ב-ChainMap:

1
2
3
4
5
6
7
8
from collections import ChainMap

dictOne = {'a':2, 'b': 3,'d':6 }

dictTwo = {'a':5, 'b': 1, 'c':2 }

chain = ChainMap(dictOne, dictTwo)
print(chain['d'])

בעזרת המשתנה maps נוכל לגשת לרשימה של המילונים.

1
print(chain.maps)

deque

deque הוא קיצור ל- Double Ended Queue.
קוראים את המילה כ-דק או deck.

הרשימה הזו היא בעצם תור דו כיווני - ניתן להכניס איברים מסוף התור או תחילת התור.
ובכך לממש שני קונספטים:

  • LIFO - Last in First Out - מחסנית
  • FIFO - First in First out - תור

ההתחלה של התור מצד שמאל, וסוף התור הוא מצד ימין.

FIFO - First in First Out - תור

תור כמו שהוא במציאות הוא רשימה שהראשון שנכנס הוא הראשון שיוצא!
אם יש לנו יותר מאלנט אחד הם נאגרים וכאשר אנחנו מוציאים אלמנט - הראשון יוצא.

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

LIFO - Last in First Out - מחסנית

מחסנית עובדת בשיטה הפוכה - האלמנט האחרון שנכנס הוא הראשון שיוצא.

דוגמא טובה לזה תהיה מחסנית קריאות קוד!
נתקלנו בזה בפרק 8 - כשלמדנו על רקורסיות:

פייתון 8 - רקורסיה

Deque API

  • deque([maxlen]) - יוצר דק עם כמות מקסימלית, אם לא כותבים כמות מקסימלית אז הדק יכול לגדול לעד.
  • append - משתמש ברשימה בצורה רגילה, מוסיף אלמנט מצד ימין.
  • appendleft - מוסיף אלמנט לצד השמאלי של הרשימה.
  • pop - מוריד אלמנט מהצד הימני של הדק.
  • popleft - מוריד אלמנט מהצד השמאלי של הדק.

תרגיל

  1. השתמשו ב-deque כדי ליצור תור.
    כתבו תכנית אשר קולטת מספרים מהמשתמש ומכניסה אותם לתור.
    כאשר המשתמש כותב pop התוכנה תדפיס את כל המספרים.
    שימו לב שהסדר צריך להיות כמו בתור!

מתודות שימושיות נוספות

  • extend - מוסיף אלמנטים לצד ימין
  • extendleft - מוסיף אלמנטים לצד שמאל
1
2
3
4
myList = [1,2,3]
deck = deque()

deck.extend(myList)

רשומות deque הן מאונדקסות:

  • index - מחפש את האינדקס של האלמנט
  • insert - מכניס אלמנט לאינדקס ספציפי
1
2
3
4
5
6
deck = deque()

deck.append(1)
deck.append(2)

deck.insert(0,0) # Just like deck.appendleft(0)

כמו כן ניתן גם לסובב את האלמנטים בפנים:

  • reverse - מחזיר את הדק בסדר הפוך.
  • rotate - מסובב את הדק ימינה או שמאלה.

תרגול

  1. עבדו את המחרוזת הבאה:
    SIMP*L*Y**C*O***D*E

על כל אות יש להוסיף את האות למחסנית,
ועל כל כוכבית להוריד אות מהמחסנית.

הדפיסו את המחסנית כל שלב.


אלו כמה סוגי רשימות שייעזרו לא לכתוב את הגלגל מחדש.

בפרק הבא נלמד כיצד לעבוד עם קבצים!

פייתון 11 - קידוד וקבצים

אהבתם? מוזמנים להביע תמיכה כאן: כוס קפה