ΜΥΥ105: Εισαγωγή στον Προγραμματισμό Λεξικά
Γιατί Λεξικά; Στις ακολουθίες (π.χ. λίστες, αλφαριθμητικά) μπορούμε να αναφερόμαστε σε ένα στοιχείο με τον αριθμητικό δείκτη του (π.χ. database[1], s[4]) Κάποιες φορές βολεύει να αναφερόμαστε σε ένα στοιχείο ή να ψάχνουμε ένα στοιχείο με το όνομά του (π.χ. database['John']) Τα λεξικά μας δίνουν αυτή τη δυνατότητα Ανάλογο της χρήσης λεξικού στην καθημερινή μας ζωή
Λεξικά Το λεξικό είναι μια συλλογή ζευγών Κάθε ζεύγος περιέχει ένα κλειδί και μια τιμή Χρησιμοποιούμε τα κλειδιά για να ψάξουμε ή να αναφερθούμε στις τιμές π.χ. κλειδί = όνομα λέξης, τιμή = ορισμός λέξης π.χ. κλειδί = όνομα, τιμή = τηλέφωνο χωρίζει κλειδί από τιμή >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'} >>> phonebook['Beth'] '9102' δεν είμαστε υποχρεωμένοι να εισάγουμε τα κλειδιά σε λεξικογραφική σειρά Χρησιμοποιούμε { } για τον ορισμό λεξικού
Μοναδικότητα κλειδιών Τα κλειδιά είναι μοναδικά σε ένα λεξικό δεν μπορεί δύο ζεύγη να έχουν τα ίδια κλειδιά Οι τιμές δεν χρειάζεται να είναι μοναδικές μετράει η τελευταία εμφάνιση του κλειδιού >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Beth': '3258’} >>> phonebook {'Beth': '3258', 'Alice': '2341'} >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '9102'} {'Cecil': '9102', 'Beth': '9102', 'Alice': '2341'}
Μετατροπή από Λίστα Η συνάρτηση dict δημιουργεί ένα λεξικό από μια λίστα πλειάδων κάθε πλειάδα είναι ένα ζεύγος-στοιχείο του λεξικού >>> items = [('name', 'Gumby'), ('age', 42)] >>> d = dict(items) >>> d {'age': 42, 'name': 'Gumby'} >>> d['name'] 'Gumby' οι τιμές ενός λεξικού μπορεί να είναι οποιουδήποτε τύπου τα κλειδιά δεν μπορεί να είναι λίστες >>> d = {23:56, 'a':25, 'b':'c', (4,5):'d', 2:[4,5]}
Άλλη χρήση της dict() Η συνάρτηση dict μπορεί να πάρει ως είσοδο και μια σειρά από στοιχεία τύπου κλειδί=τιμή >>> d = dict(name='Gumby', age=42) >>> d {'age': 42, 'name': 'Gumby'} >>> d2 = dict(23=24124,24=32434) SyntaxError: keyword can't be an expression για κλειδιά τύπου αλφαριθμητικού μόνο!
Βασικές λειτουργίες >>> d = dict(name='Gumby', age=42) >>> len(d) 2 >>> d['age'] 42 >>> d['something'] Traceback (most recent call last): File "<pyshell#13>", line 1, in <module> d['something'] KeyError: 'something' >>> 'something' in d False Ο αριθμός των κλειδιών στο λεξικό True, αν υπάρχει εγγραφή στο d με κλειδί ‘something’
Βασικές λειτουργίες εισάγει νέα εγγραφή αν δεν υπάρχει το κλειδί >>> d['something']='I don\'t know’ >>> d['something'] "I don't know" >>> 'something' in d True >>> d['age']=43 >>> d['age'] 43 >>> del d['age'] >>> 'age' in d False εισάγει νέα εγγραφή αν δεν υπάρχει το κλειδί αν υπάρχει το κλειδί, αλλάζει την υπάρχουσα εγγραφή σβήνει μια υπάρχουσα εγγραφή από το λεξικό
Ειδικά χαρακτηριστικά Τα κλειδιά πρέπει να είναι μη μεταβαλλόμενου τύπου (δεν μπορεί να είναι λίστες) Όταν ορίζουμε μια τιμή για ένα κλειδί, το ζευγάρι (κλειδί, τιμή) εισάγεται στο λεξικό αν δεν υπάρχει ήδη το κλειδί δεν γίνεται έτσι με τις λίστες >>> lst = ['a','b','c'] >>> lst[3] = 'd' Traceback (most recent call last): File "<pyshell#37>", line 1, in <module> lst[3] = 'd' IndexError: list assignment index out of range
Ειδικά χαρακτηριστικά Η εύρεση (π.χ. τελεστής in) γίνεται με βάση το κλειδί Η εύρεση σε μεγάλα λεξικά είναι ταχύτερη από την εύρεση σε μεγάλες λίστες δεικτοδότηση (indexing) μέσω κατακερματισμού (hashing) Στα λεξικά, τα στοιχεία κλειδιών-τιμών δεν έχουν κάποια συγκεκριμένη σειρά τα λεξικά είναι αταξινόμητα σύνολα, ενώ τα στοιχεία των λιστών/πλειάδων είναι σε συγκεκριμένη σειρά
Formatting με χρήση λεξικού κλειδί λεξικό >>> phonebook {'Beth': '9102', 'Cecil': '3258', 'Alice': '2341'} >>> "Cecil's phone number is %(Cecil)s." % phonebook "Cecil's phone number is 3258." >>> "Cecil's phone number is %s." % phonebook['Cecil']
Η μέθοδος clear Καθαρίζει το λεξικό από τα περιεχόμενά του >>> d = {} >>> d['name'] = 'Gumby’ >>> d['age'] = 42 >>> d {'age': 42, 'name': 'Gumby'} >>> d.clear() {}
Γιατί όχι αρχικοποίηση; >>> x = {} >>> y = x >>> x['key']='value' >>> y {'key': 'value'} >>> x = {} >>> y = x >>> x['key']='value' >>> y {'key': 'value'} >>> x.clear() {} H ανάθεση x={} απλά βάζει το x να δείχνει σε ένα νέο αντικείμενο. Το y συνεχίζει να δείχνει στο παλιό. Η κλήση της clear ζητάει από το αντικείμενο να καθαρίσει τον εαυτό του και άρα επηρεάζει και το x και το y γιατί δείχνουν στο ίδιο αντικείμενο
Η μέθοδος copy Αντιγράφει το λεξικό σε ένα άλλο λεξικό ρηχή αντιγραφή: δεν δημιουργεί αντίγραφο των αντικείμενων μέσα στο λεξικό >>> x = {'username': 'admin', 'machines': ['zeus','gaia']} >>> y = x.copy() >>> y['username']='user1' >>> y['machines'].remove('gaia') >>> y {'username': 'user1', 'machines': ['zeus']} >>> x {'username': 'admin', 'machines': ['zeus']} λίστα (μεταβαλλόμενο αντικείμενο)
Η μέθοδος copy Αντιγράφει το λεξικό σε ένα άλλο λεξικό ρηχή αντιγραφή: δεν δημιουργεί αντίγραφο των αντικείμενων μέσα στο λεξικό x = {'username': 'admin', 'machines': ['zeus','gaia']} y = x.copy() 'username' 'machines' ['zeus','gaia'] 'admin' x y 'username' 'machines' 'user1' y['username']='user1' y['machines'].remove('gaia') αν αντικαταστήσουμε ένα μη μεταβαλλόμενο αντικείμενο το πρωτότυπο δε μεταβάλλεται αν αλλάξουμε ένα μεταβαλλόμενο, το πρωτότυπο αλλάζει
Η συνάρτηση deepcopy Αντιγράφει το λεξικό σε ένα άλλο λεξικό βαθειά αντιγραφή: δημιουργεί αντίγραφο των αντικείμενων μέσα στο λεξικό >>> from copy import deepcopy >>> d = {} >>> d['names'] = ['Alfred', 'Bertrand'] >>> c = d.copy() >>> dc = deepcopy(d) >>> d['names'].append('Clive') >>> c {'names': ['Alfred', 'Bertrand', 'Clive']} >>> dc {'names': ['Alfred', 'Bertrand']}
Αρχικοποίηση μέσω fromkeys Αρχικοποίηση λεξικού με κλειδιά μόνο >>> dict.fromkeys(['name', 'age']) {'age': None, 'name': None} >>> dict.fromkeys(['name', 'age'], '(unknown)') {'age': '(unknown)', 'name': '(unknown)'} ειδική τιμή: σημαίνει «τίποτα» μια δική μας τιμή για όλα τα κλειδιά
Η μέθοδος get Ψάχνει και επιστρέφει μια τιμή με βάση το κλειδί, ενώ επιστρέφει «None» αν το κλειδί δεν υπάρχει >>> d ={'John': '3456'} >>> d['Paul'] Traceback (most recent call last): File "<pyshell#145>", line 1, in <module> d['Paul'] KeyError: 'Paul’ >>> print(d.get('Paul')) None >>> print(d.get('John')) 3456 ειδική τιμή: σημαίνει «τίποτα»
Η μέθοδος get Ψάχνει και επιστρέφει μια τιμή με βάση το κλειδί, ενώ επιστρέφει «None» αν το κλειδί δεν υπάρχει >>> d ={'John': '3456'} >>> print(d.get('Paul','N/A')) N/A αντικαθιστά το None, σε περίπτωση που δεν υπαρχει το κλειδί ‘Paul’ >>> d = dict.fromkeys(['name', 'age']) >>> print(d.get('name')) None >>> print(d.get('Paul','N/A')) N/A >>> print(d.get('name','N/A')) το ‘Paul’ δεν υπάρχει το ‘name’ υπάρχει!
Ο τελεστής in Δίνει True αν το κλειδί που παίρνει για όρισμα υπάρχει στο λεξικό, αλλίως False >>> d = {} >>> 'name' in d False >>> d['name'] = 'Eric' True
Η μέθοδοi items, keys και values >>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0} >>> d.items() [('url', 'http://www.python.org'), ('spam', 0), ('title', 'Python Web Site')] >>> list(d.keys()) ['url', 'title', 'spam'] >>> list(d.values()) ['http://www.python.org', 'Python Web Site', 0]
Η μέθοδοι pop και popitem >>> d = {'x': 1, 'y': 2, 'z': 2} >>> d.pop('y') 2 >>> d {'x': 1, 'z': 2} >>> d.popitem() ('x', 1) {'z': 2}
Η μέθοδος setdefault Παρόμοια με την get. Αν δε βρει το κλειδί, το εισάγει στο λεξικό με μια τιμή που δίνουμε εμείς >>> d ={'John': '3456'} >>> d.setdefault('Paul', 'unknown') 'unknown' >>> d {'Paul': 'unknown', 'John': '3456'} >>> d.setdefault('John', 'unknown') '3456' το κλειδί ‘Paul’ δεν υπάρχει: εισάγεται το 'Paul’: ‘unknown’ στο λεξικό το κλειδί ‘John’ υπάρχει: επιστρέφεται η τιμή του και το λεξικό δεν αλλάζει
Η μέθοδος update Εισάγει σε ένα λεξικό τα περιεχόμενα ενός άλλου. Τυχόν υπάρχουντα κλειδιά, ενημερώνονται. >>> d ={'John': '3456', 'Paul': '9123'} >>> t ={'Paul': '1234', 'Sue': '2014'} >>> d.update(t) >>> d {'Sue': '2014', 'Paul': '1234', 'John': '3456'} η τιμή του ‘Paul’ αντικαθίσταται
Άσκηση Έχω ένα πλέγμα πάνω στο οποίο κινούνται κάποια άτομα. Θέλω να αποθηκεύσω αυτή την πληροφορία σε ένα λεξικό. Πως θα φτιάξω το λεξικό αν θέλω τα κλειδιά να είναι τα ονόματα των ατόμων? Πως θα φτιάξω το λεξικό αν θέλω τα κλειδιά να είναι οι συντεταγμένες? 3 bob 2 alice tom jerry 1 1 2 3