ΜΥΥ105: Εισαγωγή στον Προγραµµατισµό Λεξικά Χειµερινό Εξάµηνο 2014
Γιατί Λεξικά; Στις ακολουθίες (π.χ. λίστες, αλφαριθµητικά) µπορούµε να αναφερόµαστε σε ένα στοιχείο µε τον αριθµητικό δείκτη του (π.χ. database[1], s[4]) Κάποιες φορές βολεύει να αναφερόµαστε σε ένα στοιχείο ή να ψάχνουµε ένα στοιχείο µε το όνοµά του (π.χ. database['john']) Τα λεξικά µας δίνουν αυτή τη δυνατότητα Ανάλογο της χρήσης λεξικού στην καθηµερινή µας ζωή 2
Λεξικά Το λεξικό είναι µια συλλογή ζευγών Κάθε ζεύγος περιέχει ένα κλειδί και µια τιµή Χρησιµοποιούµε τα κλειδιά για να ψάξουµε ή να αναφερθούµε στις τιµές π.χ. κλειδί = όνοµα λέξης, τιµή = ορισµός λέξης π.χ. κλειδί = όνοµα, τιµή = τηλέφωνο χωρίζει κλειδί από τιµή >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'} >>> phonebook['beth'] '9102' δεν είµαστε υποχρεωµένοι να εισάγουµε τα κλειδιά σε λεξικογραφική σειρά 3
Μοναδικότητα κλειδιών Τα κλειδιά είναι µοναδικά σε ένα λεξικό δεν µπορεί δύο ζεύγη να έχουν τα ίδια κλειδιά Οι τιµές δεν χρειάζεται να είναι µοναδικές χρήση τελευταίου κλειδιού >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Beth': '3258 } >>> phonebook {'Beth': '3258', 'Alice': '2341'} >>> phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '9102'} >>> phonebook {'Cecil': '9102', 'Beth': '9102', 'Alice': '2341'} 4
Μετατροπή από Λίστα Η συνάρτηση 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]} 5
Άλλη χρήση της dict() Η συνάρτηση dict µπορεί να πάρει ως είσοδο και µια σειρά από στοιχεία τύπου κλειδί=τιµή >>> d = dict(name='gumby', age=42) >>> d {'age': 42, 'name': 'Gumby'} για κλειδιά τύπου αλφαριθµητικού µόνο! 6
Βασικές λειτουργίες >>> 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' True, αν υπάρχει >>> 'something' in d εγγραφή στο d µε False κλειδί something >>> d['age']=43 >>> del d['age'] εισάγει νέα εγγραφή αν δεν υπάρχει το >>> d['something']='i don\'t know κλειδί, αλλιώς την αλλάζει 7
Ειδικά χαρακτηριστικά Τα κλειδιά πρέπει να είναι µη µεταβαλλόµενου τύπου (δεν µπορεί να είναι λίστες) Όταν ορίζουµε µια τιµή για ένα κλειδί, το ζευγάρι (κλειδί, τιµή) εισάγεται στο λεξικό αν δεν υπάρχει ήδη το κλειδί δεν γίνεται έτσι µε τις λίστες >>> 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 8
Ειδικά χαρακτηριστικά Η εύρεση (π.χ. τελεστής in) γίνεται µε βάση το κλειδί Η εύρεση σε µεγάλα λεξικά είναι γρηγορότερη από την εύρεση σε µεγάλες λίστες δεικτοδότηση (indexing) µέσω κατακερµατισµού (hashing) Στα λεξικά, τα στοιχεία κλειδιών-τιµών δεν έχουν κάποια συγκεκριµένη σειρά τα λεξικά είναι αταξινόµητα σύνολα, τα στοιχεία των λιστών/πλειάδων είναι σε συγκεκριµένη σειρά 9
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'] "Cecil's phone number is 3258." 10
Η µέθοδος clear Καθαρίζει το λεξικό από τα περιεχόµενά του >>> d = {} >>> d['name'] = 'Gumby >>> d['age'] = 42 >>> d {'age': 42, 'name': 'Gumby'} >>> d.clear() >>> d {} 11
Γιατί όχι αρχικοποίηση; >>> x = {} >>> y = x >>> x['key']='value' >>> y {'key': 'value'} >>> x = {} >>> y {'key': 'value'} >>> x = {} >>> y = x >>> x['key']='value' >>> y {'key': 'value'} >>> x.clear() >>> y {} 12
Η µέθοδος 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']} 13
Η µέθοδος copy Αντιγράφει το λεξικό σε ένα άλλο λεξικό ρηχή αντιγραφή: τα αντικείµενα δεν αντιγράφονται x = {'username': 'admin', 'machines': ['zeus','gaia']} y = x.copy() y['username']='user1' x 'username' 'machines' 'admin' ['zeus','gaia'] y 'username' 'machines' 'user1' y['machines'].remove('gaia') αν αντικαταστήσουµε ένα µη µεταβαλλόµενο αντικείµενο το πρωτότυπο δε µεταβάλλεται αν αλλάξουµε ένα µεταβαλλόµενο, το πρωτότυπο αλλάζει 14
Η συνάρτηση 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']} 15
Αρχικοποίηση µέσω fromkeys Αρχικοποίηση λεξικού µε κλειδιά µόνο >>> dict.fromkeys(['name', 'age']) {'age': None, 'name': None} «τίποτα» >>> dict.fromkeys(['name', 'age'], '(unknown)') {'age': '(unknown)', 'name': '(unknown)'} ειδική τιµή: σηµαίνει µια δική µας τιµή για όλα τα κλειδιά 16
Η µέθοδος 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 ειδική τιµή: σηµαίνει «τίποτα» 17
Η µέθοδος get Ψάχνει και επιστρέφει µια τιµή µε βάση το κλειδί, ενώ επιστρέφει «None» αν το κλειδί δεν υπάρχει >>> d ={'John': '3456'} >>> print(d.get('paul','n/a')) N/A >>> d = dict.fromkeys(['name', 'age']) >>> print(d.get('name')) None >>> print(d.get('paul','n/a')) N/A >>> print(d.get('name','n/a')) None αντικαθιστά το None, σε περίπτωση που δεν υπαρχει το κλειδί Paul το Paul δεν υπάρχει το name υπάρχει! 18
Η µέθοδος has_key Επιστρέφει True αν το κλειδί που παίρνει για όρισµα υπάρχει στο λεξικό, αλλίως False >>> d = {} >>> d.has_key('name') False >>> d['name'] = 'Eric' >>> d.has_key('name') True 19
Η µέθοδοi items, keys και values 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] 20
Η µέθοδοι pop και popitem pop: Επιστρέφει την τιµή του κλειδιού που παίρνει σαν όρισµα, µετά σβήνει το αντίστοιχο ζευγάρι pop: Επιστρέφει οποιοδήποτε ζευγάρι και το σβήνει από το λεξικό >>> d = {'x': 1, 'y': 2, 'z': 2} >>> d.pop('y') 2 >>> d {'x': 1, 'z': 2} >>> d.popitem() ('x', 1) >>> d {'z': 2} 21
Η µέθοδος setdefault Παρόµοια µε την get. Αν δε βρει το κλειδί, το εισάγει στο λεξικό µε µια τιµή που δίνουµε εµείς >>> d ={'John': '3456'} >>> d.setdefault('paul', 'unknown') 'unknown' >>> d {'Paul': 'unknown', 'John': '3456'} >>> d.setdefault('john', 'unknown') '3456' >>> d {'Paul': 'unknown', 'John': '3456'} το κλειδί Paul δεν υπάρχει: εισάγεται το 'Paul : unknown στο λεξικό το κλειδί John υπάρχει: επιστρέφεται η τιµή του και το λεξικό δεν αλλάζει 22
Η µέθοδος update Εισάγει σε ένα λεξικό τα περιεχόµενα ενός άλλου. Τυχόν υπάρχουντα κλειδιά, ενηµερώνονται. >>> d ={'John': '3456', 'Paul': '9123'} >>> t ={'Paul': '1234', 'Sue': '2014'} >>> d.update(t) >>> d {'Sue': '2014', 'Paul': '1234', 'John': '3456'} η τιµή του Paul αντικαθίσταται 23