Βασικά Στοιχεία Python 3 Compiler Lecture s 1.0 documentation Βασικά Στοιχεία Python 3 Στη συνέχεια παρουσιάζονται ορισμένα ενδιαφέροντα στοιχεία της Python 3. Αυτό που ακολουθεί δεν είναι tutorial, αν θέλετε κάτι τέτοιο μπορείτε να βρείτε εξαιρετικά κείμενα on-line. Strings Η Python προσφέρει τους κλασσικούς τύπους δεδομένων (int, string κλπ). Τα αντικείμενα των τύπων αυτών είναι immutable, δηλαδή δεν αλλάζουν τιμή (απλά, όπως φάνηκε στην προηγούμενη πράγραφο, δημιουργούνται νέα αντικείμενα). Τα strings αποτελούν έναν πολύ εύχρηστο τύπο δεδομένων και μερικά χαρακτηριστικά τους δίνονται στη συνέχεια: Σταθερές string με μονά ή διπλά εισαγωγικά s = "abcd" s2 = 'abcd' # ισοδύναμο με προηγούμενο Τα strings ανήκουν στην κατηγορία τύπων sequence (διατεταγμένης ακολουθίας), άρα μπορούμε να πάρουμε επιμέρους τμήματα >>> s = "abcdefg" >>> s[0] 'a' >>> s[3] 'd' >>> s[ 1] 'g' >>> s[1:4] 'bcd' >>> s[: 1] 'abcdef' >>> s[2:] 'cdefg' Για να καταλάβετε καλύτερα το πώς λαμβάνονται τα τμήματα μιας sequence (slicing), μπορείτε να σκεφτείτε ότι ο δείκτης i βρίσκεται ανάμεσα στα (i-1) και i στοιχεία (κι όχι πάνω στο στοιχείο i): [a b c d e f g] ^ ^ ^ ^ ^ ^ ^ ^ 0 1 2 3 4 5 6 7 το s[1:4] είναι ίσο με "bcd" Θυμηθείτε όμως ότι δεν μπορούμε να αλλάξουμε περιεχόμενα σε ένα string (είναι immutable): >>> s = "abcdefg" >>> s[3] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment Μπορούμε όμως πάντοτε να δημιουργήσουμε ένα νέο string. Για παράδειγμα, για να επιτύχουμε το προηγούμενο: >>> s = "abcdefg" >>> s = s[:3]+'x'+s[4:] >>> s 'abcxefg' Τα αντικείμενα τύπου string διαθέτουν μια μεγάλη σειρά από χρήσιμες μεθόδους (https://docs.python.org/3/library/stdtypes.html#string-methods) 1/5
Βασικά Στοιχεία Python 3 Compiler Lecture s 1.0 documentation Σύνθετα Αντικείμενα Το δυνατό σημείο της Python είναι τα σύνθετα αντικείμενα που παρέχει, τα οποία χρησιμοποιούμε για όλες τις δομές που θέλουμε να υλοποιήσουμε. Τα δύο βασικότερα είναι οι λίστες (lists) και τα λεξικά (dictionaries). Και οι δύο αυτοί τύποι αντικειμένων είναι mutable, τα αντικείμενά τους δηλαδή μπορούν να αλλάξουν περιεχόμενα. Lists Οι λίστες ανήκουν στην κατηγορία sequence και υλοποιούν μια διατεταγμένη συλλογή αντικειμένων. Τα αντικείμενα που περιέχονται στη λίστα μπορούν να είναι οποιουδήποτε τύπου (ακόμα και άλλες λίστες). Εφόσον μια λίστα είναι sequence, μπορούμε να πάρουμε μέρος της, όπως σε ένα string: i = [1,2,'abcd','ef'] i[1] 2 i[ 1] 'ef' i[: 1] [1, 2, 'abcd'] Μπορούμε ακόμα να προσπελάσουμε ένα προς ένα τα στοιχεία της λίστας με την επαναληπτική δομή for <item> in <sequence>: >>> for item in li:... print(item)... 1 2 abcd ef Σε αντίθεση με τα strings, μπορούμε να αλλάξουμε τιμή σε ένα (υπάρχον) στοιχείο μιας λίστας. Δείτε την τελευταία παράγραφο του κειμένου για να καταλάβετε καλά το επόμενο: i = [1,2,'abcd','ef'] m = li m[0] = 33 m [33, 2, 'abcd', 'ef'] i [33, 2, 'abcd', 'ef'] Μπορούμε να προσθέσουμε δυναμικά νέα στοιχεία σε μια λίστα: i = [1,2,3,'ab','cd'] i += [11,22] i [1, 2, 3, 'ab', 'cd', 11, 22] i.append(33) i [1, 2, 3, 'ab', 'cd', 11, 22, 33] Προσέξτε το όρισμα στη μέθοδο append στο προηγούμενο παράδειγμα. Δεν είναι λίστα. Αν ήταν, το αποτέλεσμα θα ήταν διαφορετικό! = [1,2,3].append([5,6]) [1, 2, 3, [5, 6]] Αν θέλαμε να προσθέσουμε το 5 και το 6 στη λίστα, θα έπρεπε: = [1,2,3] += [5,6] [1, 2, 3, 5, 6] 2/5
Βασικά Στοιχεία Python 3 Compiler Lecture s 1.0 documentation Ή εναλλακτικά (η μέθοδος extend() ισοδυναμεί με το + σε λίστες): = [1,2,3].extend([5,6]) [1, 2, 3, 5, 6] Οι λίστες είναι δομές ειδικά βελτιστοποιημένες για ταξινόμηση (sorting). Εάν θέλουμε να ταξινομήσουμε πολύ γρήγορα μια σειρά στοιχείων, η χρήση λίστας είναι MUST!!! = [6,8, 1,11].sort() [ 1, 6, 8, 11] Dictionaries Τα λεξικά (dictionaries) είναι τύπου mapping: ζεύγη αντιστοιχιών (κλειδιού-τιμής). Κάθε κλειδί πρέπει να είναι μοναδικό, αλλά όχι απαραίτητα του ίδιου τύπου με τα άλλα. Δεν μπορείτε να χρησιμοποιήσετε λίστες ή λεξικά ως κλειδιά. Η τιμή που αντιστοιχεί σε ένα κλειδί μπορεί να είναι οποιουδήποτε τύπου. Οι πιο κοινές λειτουργίες σε λεξικά δίνονται στη συνέχεια. Δημιουργήστε ένα κενό ή ένα αρχικοποιημένο με μερικά στοιχεία λεξικό: >>> d = {} >>> da = { 'mike': 32, 'nick': 43 } Προσθέστε ένα νέο ζεύγος κλειδιού-τιμής (αν υπάρχει το κλειδί, παίρνει τη νέα τιμή): >>> da['stef'] = 67 >>> da['mike'] = 'oops' >>> da {'mike': 'oops', 'stef': 67, 'nick': 43} Ελέγξτε αν ένα κλειδί υπάρχει στο λεξικό: >>> if 'stef' in da:... print('found')... found Η απόπειρα προσπέλασης ενός κλειδιού που δεν υπάρχει, προκαλεί σφάλμα εκτέλεσης! Πρέπει πάντα να εκτελείτε τον έλεγχο ύπαρξης του κλειδιού! >>> da = { 'mike': 32, 'nick': 43 } >>> da['stef'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'stef' Προσπελάστε σε loop ένα-ένα τα ζεύγη κλειδιού-τιμής (η σειρά που επιστρέφονται τα στοιχεία εξαρτάται από την υλοποίηση της Python και δεν πρέπει να θεωρείται ντετερμινιστική): >>> for k,v in da.items():... print(k,v)... mike 32 stef 67 3/5
Βασικά Στοιχεία Python 3 Compiler Lecture s 1.0 documentation Τα λεξικά είναι δομές ειδικά βελτιστοποιημένες για αναζήτηση (searching). Εάν θέλουμε να αναζητήσουμε πολύ γρήγορα ένα στοιχείο μέσα σε ένα μεγάλο σύνολο, η χρήση λεξικού είναι MUST!!! Αρχεία Κειμένου Αν ξέρουμε ότι το ένα αρχείο κειμένου δεν είναι μεγάλο, μπορούμε να το διαβάσουμε με τη μία σε ένα string: fp = open('test.txt','r') text = fp.read() fp.close() print(text) Μπορούμε όμως με μεγαλύτερη ασφάλεια να το διαβάσουμε γραμμή προς γραμμή: fp = open('test.txt','r') for line in fp: print(line) fp.close() Στη δεύτερη περίπτωση: Κάθε γραμμή κρατά το τελικό newline χαρακτήρα \n Το αρχείο, ως προς την ανάγνωση, συμπεριφέρεται ως sequence από strings, έτσι μπορούμε να εφαρμόσουμε το επαναληπτικό for.. in.. που έχουμε ήδη δει. Duck Typing: Αν περπατά σαν την πάπια και κάνει σαν την πάπια, τότε για μας είναι πάπια!. Στις γλώσσες με δυναμικό τύπο δεδομένων, δεν είναι δυνατός ο έλεγχος εκ των προτέρων για το αν επιτρέπεται μια συγκεκριμένη λειτουργία σε ένα αντικείμενο. Αντί αυτού, η γλώσσα αρκείται στο ότι το αντικείμενο παρέχει τη συγκεκριμένη λειτουργία κατά τη στιγμή της εκτέλεσης, ανεξάρτητα από τον τύπο του. Αν π.χ. ένα αντικείμενο συμπεριφέρεται σαν λίστα ως προς την προσπέλαση των στοιχείων του, τότε μπορεί να χρησιμοποιηθεί σαν λίστα, ανεξάρτητα από το τι πραγματικά είναι. Παράδειγμα: Συχνότητα Εμφάνισης Λέξεων Ας εφαρμόσουμε τα προηγούμενα σε ένα συνοπτικό παράδειγμα. Υποθέστε ότι θέλουμε να διαβάσουμε ένα αρχείο κειμένου και να βρούμε τη συχνότητα εμφάνισης κάθε λέξης. Αυτό γίνεται εύκολα με ένα λεξικό: # dictionary with words as keys d = {} fp = open('test.txt','r') for line in fp: l = line.lower().split() # convert to lowercase # then split on whitespaces for word in l: # l is a list of words if word in d: # if word already in dict d[word] += 1 # incr counter else: # word not in dict d[word] = 1 # 1st time fp.close() # create list to sort per count wl = [] # use (count,word) pairs, to sort by count first for word,count in d.items(): 4/5
# sort per count wl.sort() Βασικά Στοιχεία Python 3 Compiler Lecture s 1.0 documentation wl.append((count,word)) # print words and counts for count,word in wl: print(word,count) Πιθανές βελτιώσεις: Θα παρατηρήσατε βέβαια ότι ο προηγούμενος κώδικας δεν είναι ολοκληρωμένος. Π.χ. τα σημεία στίξης θεωρούνται μέρος της λέξης. Όλα αυτά όμως μπορούν να διορθωθούν εύκολα όπως θα δούμε αργότερα! Μεταβλητές και Αναφορές Δεν χρειάζεται να ξέρετε όσα λέγονται στη συνέχεια για να προγραμματίσετε σε Python. Η γλώσσα τα υλοποιεί για εσάς. Είναι όμως χρήσιμα για όσους προέρχονται από τον κόσμο της C/C++! Στην Python οι μεταβλητές δεν δηλώνονται και μπορούν να περιέχουν διάφορους τύπους αντικειμένων κατά τη διάρκεια ζωής τους. Το πιο κάτω είναι απολύτως νόμιμο: i = 23 i += 1 j = i i = "hello" Αυτό που συμβαίνει κατά την εκτέλεση των παραπάνω είναι: Δημιουργείται ένα αντικείμενο τύπου int με τιμή 23 Το όνομα i συνδέεται με το αντικείμενο αυτό Δημιουργείται ένα νέο αντικείμενο τύπου int με τιμή 23+1 Το όνομα i συνδέεται με το νέο αυτό αντικείμενο Το όνομα j συνδέεται με το αντικείμενο, στο οποίο αναφέρεται το i (με τιμή 24) Δημιουργείται ένα αντικείμενο τύπου str με τιμή "hello" Το όνομα i συνδέεται με το νέο αυτό αντικείμενο Κάποια στιγμή (μη ντετερμινιστική για εμάς!) η Python θα ανακυκλώσει αυτόματα όσα αντικείμενα δεν συνδέονται με μεταβλητές (garbage collection). 5/5