לדלג לתוכן

1.3 מבני נתונים הרצאה

  • אנחנו משתמשים במשתנים כדי לשמור מידע.
  • לכל משתנה יש סוג, אנחנו קוראים לזה "סוג משתנה" או באנגלית "data type"
  • יש המון סוגים של datatypes, בשיעור הזה אנחנו נעבור על החשובים.

משתנים

  • כשאנחנו מגדירים משתנים, נוכל להשתמש בהם רק אחרי שהגדרנו אותם, למשל בקוד הבא:
    x = 3
    print(x)
    
    print(x+5)
    
  • כפי שניתן לראות בקוד למעלה, רק אחרי שהגדרנו את x נוכל להשתמש בו.
  • אם ננסה להשתמש בx לפני שהגדרנו אותו, נקבל שגיאה מפייתון והתוכנה שכתבנו תקרוס.
    print(x)
    x = 3
    print(x)
    
  • אתם מוזמנים לנסות להריץ את הקוד ולראות שתחזור שגיאה.

מספר שלם

  • מספר שלם או באנגלית "integer" הוא סוג של משתנה שקיים בפייתון, אותו כבר הספקנו להכיר כ-"int" בפרק הקודם.
    x = 3
    

מספר עשרוני

  • מספר עשרוני או באנגלית "float" הוא סוג של משתנה שקיים בפייתון שמייצג מספרים עשרוניים, למשל: 3.14, 2.71, 1.61. המילה אשר מייצגת float היא פשוט float כמו שהמילה שמייצגת integer היא int.
    x = 3.14
    5 / 3
    

מחרוזות

  • מחרוזת היא רשימה של אותיות
    פעולות נפוצות במחרוזות:
  • חיבור בין מחרוזות:

    str_concatenated = "Hello, " + "World!"
    print(str_concatenated) # will output hello, world!
    

  • כפל מחרוזות:

    str_repeated = "Python " * 3
    print(str_repeated) # will output PythonPythonPython
    

  • קבלת אורך מחרוזת, כלומר, מספר התוים במחרוזת מסוימת.

    str_length = len("Hello")
    print(str_length) # will output 5
    

  • גישה לאות מסויימת במחרוזת.

    substring_1 = "Python"[0]
    substring_2 = "Python"[1]
    substring_3 = "Python"[2]
    print(substring_1) # will output P 
    print(substring_2) # will output y
    print(substring_3) # will output t
    

  • שימו לב, התו הראשון מיוצג על ידי הספרה 0 ולא 1, והסיבה לכך, בגדול, היא בגלל שככה המחשב קורא קוד.

  • חיתוך מחרוזת.

    substring = "Python"[1:4]
    print(substring) # will output yth
    

  • הפעולה תחתוך את מן המחרוזת "Python" את התוים הנמצאות מאחורי המספר 1, המספר 2, המספר 3 ושומר אותם כמחרוזת חדשה.
  • שימו לב, אפילו שכתוב 1:4, התיו הנמצא מאחורי המקום 4 לא ישמר כחלק מהמחרוזת החדשה מכיוון שזה שומר מן הספר הראשונה עד ספרה אחת לפני האחרונה.

  • פיצול מחרוזת לרשימה, מפצל על פי פרמטר - במקרה הזה מפצל מרווחים.

  • ניתן לבצע פעולה זו על ידי הפונקציה ( )split.
  • בדוגמה למטה, הפעולה ( )split. מוחקת את הרווחים הנצאים במשתנה string, שומרת את כל התוים הנמצאים בין רווח לרווח ושומרת אותם כאיברים נפרדים ברשימה.

    string = "My name is Amit"
    splitted_str = string.split(" ")
    print(splitted_str) # will output ['My', 'name', 'is', 'Amit']
    

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

  • בדוגמה למטה הכנו רשימה בשם word_list.
  • לאחר מכן השתמשנו בפעולה ( )join. בשביל לחבר את כל המילים ברשימה word_list בשילוב של רווח בין מילה למילה.

    word_list = ["Python", "is", "awesome"]
    joined_str = " ".join(word_list)
    print(joined_str) # will output Python is awesome
    

  • הפיכת מחרוזת מאותיות קטנות לגדולות וההפך.

    uppercase_str = "hello".upper()
    print(uppercase_str) # will output HELLO
    lowercase_str = "WORLD".lower()
    print(lowercase_str) # will output world
    

  • אותיות מיוחדות:

    print("Hello \n World") # will output: Hello
                                        #  world
    print("Hello \t World") # will output: Hello     World
    print("Hello \"World\" .") # will output: Hello "World" .
    print("i can print a backslash: \\") # will output: i can print a backslash: \
    print(r"i can print special charecters: \n \ ") 
    # will output: i can print special charecters: \n \
    

רשימה

  • רשימה ב-Python היא מבנה נתונים שמאפשר לאחסן אוסף סדור של פריטים (items), שיכולים להיות מסוגים שונים. הרשימה מוגדרת באמצעות סוגריים מרובעים [], והפריטים מופרדים בפסיקים.
    פעולות נפוצות עם רשימות:
  • יצירת רשימה:

    my_list = [1, 2, 3, 4, 5]
    

  • גישה לאיברים ברשימה לפי מיקום ברשימה:

  • שימו לב שזה דומה לחלוטין למציאת רכיב במחרוזת כפי שהוזכר קודם לכן.

    element = my_list[0]
    element = my_list[1]
    

  • חיתוך רשימה:

  • שימו לב שזה דומה לחלוטין לחיתוך מחרוזת כפי שהוזכר קודם לכן.

    subset = my_list[1:4]
    

  • חיבור רשימות:

    my_list = [1, 2, 3, 4, 5]
    new_list = my_list + [6, 7, 8]
    print(new_list) # will output: [1, 2, 3, 4, 5, 6, 7, 8]
    

  • כפל רשימות:

    my_list = [1, 2, 3, 4, 5]
    repeated_list = my_list * 2
    print(repeated_list) # will output: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    

  • קבלת אורך רשימה (כמה איברים נימצאים ברשימה):

    my_list = [1, 2, 3, 4, 5]
    length = len(my_list)
    print(length) # will output: 5
    

  • הוספת איבר לסוף הרשימה:

    my_list = [1, 2, 3, 4, 5]
    my_list.append(9)
    print(my_list) # will output: [1, 2, 3, 4, 5, 9]
    

  • מחיקת איבר מסויים מהרשימה:

    my_list = [1, 2, 3, 4, 5]
    my_list.remove(3)  # Removes the number 3 from the list
    print(my_list) # will output: [1, 2, 4, 5]
    

  • סידור רשימה:

  • זוהי דרך לסדר רשימה על פי סדר עולה מסוים.
  • בדוגמה 1 ניתן לראות שהמחשב יסדר את המספרים מהקטן לגדול ובדוגמה השנייה המחשב יסד את האותיות לפי סדר ה-ABC
    my_list_1 = [3, 7, 4, 9, 2]  
    sorted_list_1 = sorted(my_list_1)  
    print(sorted_list_1) # will output: [2, 3, 4, 7, 9]
    
    
    my_list_2 = ['B', 'R', 'A', 'Y', 'D']  
    sorted_list_2 = sorted(my_list_2)  
    print(sorted_list_2) # will output: ['A', 'B', 'D', 'R', 'Y']
    

מילון

  • מילון ב-Python הוא מבנה נתונים שמאפשר לאחסן זוגות של מפתחות וערכים. כל מפתח (key) במילון הוא ייחודי ומצביע על ערך מסוים (value). המילון ב-Python מוגדר באמצעות סוגריים מסולסלים {} ומפרידים בין מפתח לערך שלו על ידי " : ".
    פעולות נפוצות עם מילון:
  • יצירת מילון:
  • שימו לב שניתן לרשום מילון בשני הדרכים המוצגות למטה, כלומר, שני הדרכים קבילות.

    my_dict = {
        'name': 'John',
        'age': 25,
        'city': 'New York'
    }
    
    my_dict = {'name': 'John', 'age': 25, 'city': 'New York'}
    

  • גישה לערך של מפתח במילון:

    name = my_dict['name']
    

  • שינוי ערך של מפתח במילון:

    my_dict['age'] = 26
    

  • מחיקת מפתח מהמילון + גישה למפתח שמחקנו

    removed_value = my_dict.pop('city')
    

  • גישה לרשימה של המפתחות של המילון

    keys = my_dict.keys()
    

  • גישה לרשימה של הערכים של המילון

    values = my_dict.values()
    

  • מיזוג 2 מיליונים למילון אחד:

    new_dict = {'gender': 'Male'}
    my_dict.update(new_dict)
    

סט (set)

סט (set) ב-Python הוא אוסף לא סדור של פריטים ייחודיים, כלומר, הוא לא מאפשר כפילויות. הוא מוגדר באמצעות סוגריים מסולסלים {} או באמצעות הפונקציה set(). הסטים ב-Python אינם תומכים בגישה לפי אינדקס כמו רשימות, כלומר, אי אפשר לגשת לערך מסוים בסט על ידי המקום הסידורי שלו.
בנוסף, הם מסודרים תמיד. האיברים של סטים יהיו מסודרים לפי הערך שלהם לא כמו רשימות, למשל אם נגדיר את הסט הבא: {2, 1, 3} הוא יתורגם ל {3, 2, 1}.
פעולות נפוצות על סטים:
- יצירת סט:

set1 = {1, 2, 3, 4, 5}
set2 = {3, 4, 5, 6, 7}

  • הוספת איברים לסטים:
  • בדרך זו תוכלו להוסיף איברים לסטים שלכם.

    set1 = {1, 2, 3, 4, 5}
    set1.add(6)
    set1.update([7, 8, 9])
    print(set1) # will print: {1, 2, 3, 4, 5, 6, 7, 8, 9}
    

  • מחיקת איברים מסטים

    set1 = {1, 2, 3, 4, 5}
    set1.remove(3)  # Remove a specfic element by their value
    print(set1) # will print: {1, 2, 4, 5}
    

  • פעולות נפוצות על 2 סטים במקביל:

    • פעולת union - מחזיר סט של שילוב שני הסטים.
    • פעולת intersection (חיתוך) - מחזיר סט של רק האיברים שזהיים בין שני הסטים.
    • פעולת difference - מחזיר סט של האיברים של הסט הראשון השונים מן האיברים של הסט השני (לא מחזיר את הסט של האיברים הנמצאים בסט השני וואינם נמצאים בראשון).
    • פעולת symmetric_difference - מחזיר סט של האיברים השונים בין שני הסטים.
      set1 = {1, 2, 3, 4, 5}
      set2 = {3, 4, 5, 6, 7}
      
      a = set1.union(set2)
      print(a) # will print: {1, 2, 3, 4, 5, 6, 7} 
      
      b = set1.intersection(set2)
      print(b) # will print: {3, 4, 5}
      
      c = set1.difference(set2)
      print(c) # will print: {1, 2}
      
      d = set1.symmetric_difference(set2)
      print(d) # will print: {1, 2, 6, 7}
      
  • יצירת העתק של הסט - תמיד תשתמשו בזה כשאתם רוצים להעתיק סט!

    set1 = {1, 2, 3, 4, 5}
    set_copy = set1.copy()
    print(set_copy) # will print: {1, 2, 3, 4, 5}
    

  • מחיקת כל האיברים בסט:

  • הסיבה שבגללה המחשב מחזיר None היא בגלל שבעצם הדפסנו כלום, המשתנה x, במילים אחרות, שווה לשום דבר.
    set1 = {1, 2, 3, 4, 5}
    x = set1.clear()
    print(x) # will print: None
    

טאפל (tuple)

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

tuple1 = (1, 2, 3, 4, 5)
tuple2 = (3, 4, 5, 6, 7)
tuple3 = 1, 2, 3, 4, 5

  • גישה לאיברים בטאפל:

    tuple1 = (1, 2, 3, 4, 5)
    
    first_element = tuple1[0]
    print(first_element) # will print: 1
    
    last_element = tuple1[-1]
    print(last_element) # will print: 5
    

  • חיתוך טאפל:

    tuple1 = (1, 2, 3, 4, 5)
    subset_tuple = tuple1[1:4]
    print(subset_tuple) # will print: (1, 2, 3)
    

  • חיבור וכפל טאפלים:

    tuple1 = (1, 2, 3, 4, 5)
    tuple2 = (3, 4, 5, 6, 7)
    concatenated_tuple = tuple1 + tuple2
    print(concatenated_tuple) # will print: (1, 2, 3, 4, 5, 3, 4, 5, 6, 7) 
    
    repeated_tuple = tuple1 * 2
    print(repeated_tuple) # will print: (1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
    

  • קבלת האורך של טאפל:

    tuple1 = (1, 2, 3, 4, 5)
    tuple_length = len(tuple1)
    print(tuple_length) # will print: 5
    

  • בדיקת האם איבר בטאפל:

  • יחזיר אמת או שקר בהתאם להאים האיבר באמת נמצא בטופל או לא.

    tuple1 = (1, 2, 3, 4, 5)
    is_in_tuple = 4 in tuple1
    print(is_in_tuple) # will print: True
    

  • אז מתי משתמשים בטאפלים? בוא נראה דוגמה אחת נפוצה:

    # Unpacking operator
    coordinates = (3, 4)
    x, y = coordinates
    

  • הפעולת פיצול למעלה נקראת "unpacking", ובדרך כלל אנחנו משתמשים בטאפלים בשביל unpacking.

רשימות נגד טאפלים נגד סטים

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

סיקואנס

  • סיקואנס או באנגלית "sequence" היא תכונה שקיימת לdatatypes, התכונה הזו קיימת לdatatypes כמו רשימה, מחרוזת ומילון.

    l = ["h", "e", "l", "l", "o"]
    s = "hello"
    d = {
         "level": 3,
         "difficulty": "hard"
    }
    

  • כל סיקואנס אנחנו יכולים לחצות (slicing).

    print(l[0])
    print(l[1])
    print(l[2])
    print(s[0])
    print(d["level"])
    print(d["difficulty"])
    print(l[-1])
    

  • range slicing
    print(l[1:3])
    print(l[:2])
    
  • step based slicing
    print(l[0:3:2])
    print(l[::-1])
    

מיוטאבילטי

  • מיוטאבילטי או באנגלית "mutability" היא תכונה בפייתון של datatypes שמציינת האם האובייקט ניתן לשינוי אחרי שנוצר.
  • במילים פשוטות יותר, אם אובייקט הוא "mutable" הוא יכול לשתנות
  • ואם האובייקט הוא "immutable" הוא לא ניתן לשינוי אחרי שנוצר, כמו טאפל.

דוגמאות:
- אובייקטים מיוטאבילים: רשימה, מילון, וסטים. אפשר להוסיף, להוריד ולשנות איברים באובייקטים האלו.

my_list = [1, 2, 3]
my_list[0] = 10  # This modifies the first element of the list
  • אובייקטים immutable: טאפלים, ומחרוזות. אחרי שאנחנו יוצרים אותם איי אפשר לשנות את הערך שלהם.
    my_tuple = (1, 2, 3)
    # The following would result in an error because tuples are immutable
    # My_tuple[0] = 10
    # "hello"[0] = "a"
    

פיצול (unpacking)

  • בפייתון אפשר לפצל רשימות וכדומה למשתנים קטנים יותר.
    a, b, c, d = [1, 2, 3, 4]
    a, b, c, d = (1, 2, 3, 4)
    a, b, _, d = (1, 2, 3, 4)
    a, *_, d = (1, 2, 3, 4)
    
  • דוגמה לשימוש בunpacking עם split
    expression = "5 + 3"
    num1, op, num2 = expression.split()
    

כלום - None

  • כלום.
    x = None
    
  • בעתיד נראה איך המילה השמורה הזו (keyword) משמשמת אותנו.