Η κλάση dict στην Python παρέχει πολλές χρήσιμες μεθόδους για να δουλεύεις με λεξικά.
Κάποιες παρουσιάστηκαν στην έννοια για τα dicts.
Εδώ καλύπτουμε μερικές ακόμη, μαζί με κάποιες τεχνικές για να διατρέχεις και να χειρίζεσαι λεξικά.
setdefault() για Εισαγωγή χωρίς ΣφάλματαΗ έννοια του λεξικού κάλυψε ήδη ότι η .get(key, <default value>) επιστρέφει ένα υπάρχον value ή το default value όταν ένα key δεν βρίσκεται στο λεξικό, αποφεύγοντας έτσι ένα KeyError.
Αυτό λειτουργεί καλά σε περιπτώσεις που δεν θέλεις επιπλέον χειρισμό σφαλμάτων, αλλά δεν μπορείς να είσαι σίγουρος ότι το key που ψάχνεις θα υπάρχει.
Για μια εξίσου "ασφαλή" (χωρίς KeyError) λειτουργία εισαγωγής, υπάρχει η μέθοδος .setdefault(key, <default value>).
Η setdefault(key, <default value>) επιστρέφει το value αν το key βρίσκεται στο λεξικό.
Αν το κλειδί δεν βρεθεί, εισάγει το ζεύγος (key, default value) και επιστρέφει το default value για χρήση.
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
# Looking for the value associated with key "Rock Brown".
# The key does not exist, so it is added with the default value, and the value is returned.
>>> palette_I.setdefault('Rock Brown', '#694605')
'#694605'
# The (key, default value) pair has now been added to the dictionary.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}
fromkeys() για Γέμισμα ενός Λεξικού από ένα ΕπαναλήψιμοΓια να γεμίσεις γρήγορα ένα λεξικό με διάφορα keys και προεπιλεγμένες τιμές, η μέθοδος κλάσης fromkeys(iterable, <default value>) διατρέχει ένα επαναλήψιμο από keys και δημιουργεί ένα νέο dict.
Όλα τα values θα οριστούν στην default value που δίνεις:
>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')
{'Grassy Green': 'fill in hex color here',
'Purple Mountains Majesty': 'fill in hex color here',
'Misty Mountain Pink': 'fill in hex color here'}
Οι μέθοδοι .keys(), .values() και .items() επιστρέφουν επαναλήψιμες όψεις ενός λεξικού.
Αυτές οι όψεις μπορούν να χρησιμοποιηθούν για να διατρέξεις εύκολα τις καταχωρίσεις χωρίς να τις αλλάξεις.
Οι όψεις είναι επίσης δυναμικές: όταν αλλάζουν τα δεδομένα του λεξικού, το αντίστοιχο view object αντικατοπτρίζει την αλλαγή:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
# Using .keys() returns a list of keys.
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])
# Using .values() returns a list of values.
>>> palette_I.values()
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])
# Using .items() returns a list of (key, value) tuples.
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])
# Views are dynamic. Changing values in the dict changes all of the associated views.
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
>>> palette_I['Deep Red'] = '#932432'
>>> palette_I.values()
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])
.keys(), .values() και .items()
Στην Python 3.7+, τα dicts διατηρούν τη σειρά με την οποία εισάγονται οι καταχωρίσεις, επιτρέποντας επανάληψη Πρώτο μέσα, πρώτο έξω (FIFO) όταν χρησιμοποιείς τις .keys(), .values() ή .items().
Στην Python 3.8+, οι όψεις είναι επίσης αντιστρέψιμες.
Έτσι μπορείς να διατρέξεις κλειδιά, τιμές ή ζεύγη (key, value) με σειρά Τελευταίο μέσα, πρώτο έξω (LIFO) χρησιμοποιώντας τις reversed(<dict>.keys()), reversed(<dict>.values()) ή reversed(<dict>.items()):
>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
# Iterating in insertion order (First in, first out)
>>> for item in palette_II.items():
... print(item)
...
('Factory Stone Purple', '#7c677f')
('Green Treeline', '#478559')
('Purple baseline', '#161748')
# Iterating in the reverse direction. (Last in, first out)
>>> for item in reversed(palette_II.items()):
... print (item)
...
('Purple baseline', '#161748')
('Green Treeline', '#478559')
('Factory Stone Purple', '#7c677f')
Τα λεξικά δεν έχουν ενσωματωμένη μέθοδο ταξινόμησης.
Ωστόσο, μπορείς να ταξινομήσεις μια όψη ενός dict χρησιμοποιώντας την ενσωματωμένη συνάρτηση sorted() με το dict.items().
Η ταξινομημένη όψη μπορεί μετά να χρησιμοποιηθεί για να δημιουργήσεις ένα νέο λεξικό.
Όπως και στην επανάληψη, η προεπιλεγμένη ταξινόμηση γίνεται πάνω στα keys του λεξικού.
# Default ordering for a dictionary is insertion order (First in, first out).
>>> color_palette = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
# The default sort order for a dictionary uses the keys.
>>> sorted_palette = dict(sorted(color_palette.items()))
>>> sorted_palette
{'Factory Stone Purple': '#7c677f',
'Grassy Green': '#9bc400',
'Green Treeline': '#478559',
'Misty Mountain Pink': '#f9c5bd',
'Purple Mountains Majesty': '#8076a3',
'Purple baseline': '#161748'}
.update()
Η <dict_one>.update(<dict_two>) μπορεί να χρησιμοποιηθεί για να συνδυάσεις δύο λεξικά.
Αυτή η μέθοδος παίρνει τα ζεύγη (key,value) του <dict_two> και τα γράφει στο <dict_one>:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple Baseline': '#161748'}
>>> palette_I.update(palette_II)
# Note that new items from palette_II are added.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}
Όπου τα κλειδιά των δύο λεξικών επικαλύπτονται, το value στο dict_one αντικαθίσταται από το αντίστοιχο value του dict_two:
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
>>> palette_III = {'Grassy Green': (155, 196, 0), 'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> palette_I.update(palette_III)
# Overlapping values in palette_I are replaced with values from palette_III
>>> palette_I
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559', 'Purple baseline': '#161748'}
| και |=)Η Python 3.9 εισάγει έναν διαφορετικό τρόπο συγχώνευσης dicts: τους τελεστές union.
Το dict_one | dict_two δημιουργεί ένα νέο λεξικό, αποτελούμενο από τα ζεύγη (key, value) των dict_one και dict_two.
Όταν τα δύο λεξικά μοιράζονται κλειδιά, οι τιμές του dict_two υπερισχύουν.
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
>>> new_dict = palette_I | palette_II
>>> new_dict
...
{'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
Το dict_one |= other συμπεριφέρεται παρόμοια με το <dict_one>.update(<other>), αλλά σε αυτή την περίπτωση το other μπορεί να είναι είτε ένα dict είτε ένα επαναλήψιμο από ζεύγη (key, value):
>>> palette_III = {'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> new_dict |= palette_III
>>> new_dict
...
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
Για μια λεπτομερή εξήγηση των λεξικών και των μεθόδων για να δουλεύεις μαζί τους, το επίσημο tutorial και η επίσημη αναφορά της βιβλιοθήκης είναι εξαιρετικά σημεία εκκίνησης.
Το Real Python και το Finxter έχουν επίσης πολύ αναλυτικά άρθρα για τα λεξικά της Python.
Η Mecha Munch™, μια εταιρεία αυτοματοποίησης αγορών τροφίμων, σε προσέλαβε μόλις για να δουλέψεις στην εφαρμογή παραγγελιών της. Η ομάδα σου έχει αναλάβει να φτιάξει ένα MVP (ελάχιστο βιώσιμο προϊόν) που διαχειρίζεται όλες τις βασικές δραστηριότητες του καλαθιού αγορών, επιτρέποντας στους χρήστες να προσθέτουν, να αφαιρούν και να ταξινομούν τις παραγγελίες με τα ψώνια τους. Ευτυχώς, μια άλλη ομάδα αναλαμβάνει όλα τα θέματα χρημάτων και ολοκλήρωσης της αγοράς!
Το MVP θα πρέπει να επιτρέπει στον χρήστη να προσθέτει προϊόντα στο καλάθι αγορών του. Αυτό μπορεί να είναι ένα μεμονωμένο προϊόν ή πολλά προϊόντα μαζί. Επειδή πρόκειται για MVP, η ποσότητα του προϊόντος δηλώνεται με επαναλήψεις. Αν ένας χρήστης θέλει να προσθέσει 2 Oranges, το 'Oranges' θα εμφανιστεί δύο φορές στο iterable εισόδου. Αν ο χρήστης έχει ήδη το προϊόν στο καλάθι του, η ποσότητα στο καλάθι θα πρέπει να αυξηθεί κατά 1. Αν το προϊόν είναι νέο στο καλάθι, θα πρέπει να προστεθεί με ποσότητα 1.
Δημιούργησε τη συνάρτηση add_item(<current_cart>, <items_to_add>) που παίρνει ως ορίσματα ένα λεξικό καλαθιού και οποιοδήποτε iterable τύπου λίστας με τα προϊόντα που θα προστεθούν.
Θα πρέπει να επιστρέφει ένα νέο/ενημερωμένο λεξικό καλαθιού αγορών για τον χρήστη.
>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
('Apple', 'Apple', 'Orange', 'Apple', 'Banana'))
{'Banana': 4, 'Apple': 5, 'Orange': 2}
>>> add_item({'Banana': 3, 'Apple': 2, 'Orange': 1},
['Banana', 'Orange', 'Blueberries', 'Banana'])
{'Banana': 5, 'Apple': 2, 'Orange': 2, 'Blueberries': 1}
Ωχ. Φαίνεται ότι η ομάδα προϊόντος επιδίδεται σε υπέρμετρη επέκταση λειτουργιών. Θέλουν να προσθέσουν επιπλέον λειτουργικότητα στο MVP. Η εφαρμογή πρέπει τώρα να δημιουργεί ένα καλάθι αγορών διαβάζοντας προϊόντα από την εφαρμογή σημειώσεων του χρήστη. Βολικό για τους χρήστες, αλλά λίγο περισσότερη δουλειά για την ομάδα.
Δημιούργησε τη συνάρτηση read_notes(<notes>) που μπορεί να πάρει ως όρισμα οποιοδήποτε iterable τύπου λίστας.
Η συνάρτηση θα πρέπει να αναλύει τα προϊόντα και να δημιουργεί ένα λεξικό/καλάθι αγορών του χρήστη.
Κάθε προϊόν θα πρέπει να προστίθεται με ποσότητα 1.
Το νέο καλάθι του χρήστη θα πρέπει στη συνέχεια να επιστραφεί.
>>> read_notes(('Banana','Apple', 'Orange'))
{'Banana': 1, 'Apple': 1, 'Orange': 1}
>>> read_notes(['Blueberries', 'Pear', 'Orange', 'Banana', 'Apple'])
{'Blueberries' : 1, 'Pear' : 1, 'Orange' : 1, 'Banana' : 1, 'Apple' : 1}
Η εφαρμογή έχει μια ενότητα "Ιδέες" που είναι γεμάτη με έτοιμες συνταγές από διάφορες κουζίνες. Ο χρήστης μπορεί να επιλέξει οποιαδήποτε από αυτές τις συνταγές και όλα τα υλικά της να προστεθούν αυτόματα στο καλάθι αγορών του. Ο υπεύθυνος του έργου σού ζήτησε να δημιουργήσεις έναν τρόπο για να επεξεργάζεσαι αυτές τις συνταγές της ενότητας "Ιδέες", αφού η ομάδα περιεχομένου αλλάζει συνεχώς υλικά και ποσότητες.
Δημιούργησε τη συνάρτηση update_recipes(<ideas>, <recipe_updates>) που παίρνει ως ορίσματα ένα λεξικό "Ιδέες" και ένα iterable με ενημερώσεις συνταγών.
Η συνάρτηση θα πρέπει να επιστρέφει το νέο/ενημερωμένο λεξικό "Ιδέες".
>>>update_recipes(
{'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}},
(('Banana Bread', {'Banana': 4, 'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3}),)
)
...
{'Banana Bread': {'Banana': 4, 'Walnuts': 2, 'Flour': 1, 'Butter': 1, 'Milk': 2, 'Eggs': 3},
'Raspberry Pie': {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1}}
>>> update_recipes(
{'Banana Bread' : {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
'Raspberry Pie' : {'Raspberry': 1, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1},
'Pasta Primavera': {'Eggs': 1, 'Carrots': 1, 'Spinach': 2, 'Tomatoes': 3, 'Parmesan': 2, 'Milk': 1, 'Onion': 1}},
[('Raspberry Pie', {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2}),
('Pasta Primavera', {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1}),
('Blueberry Crumble', {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3})]
)
...
{'Banana Bread': {'Banana': 1, 'Apple': 1, 'Walnuts': 1, 'Flour': 1, 'Eggs': 2, 'Butter': 1},
'Raspberry Pie': {'Raspberry': 3, 'Orange': 1, 'Pie Crust': 1, 'Cream Custard': 1, 'Whipped Cream': 2},
'Pasta Primavera': {'Eggs': 1, 'Mixed Veggies': 2, 'Parmesan': 2, 'Milk': 1, 'Spinach': 1, 'Bread Crumbs': 1},
'Blueberry Crumble': {'Blueberries': 2, 'Whipped Creme': 2, 'Granola Topping': 2, 'Yogurt': 3}}
Μόλις ένας χρήστης ξεκινήσει ένα καλάθι, η εφαρμογή τού επιτρέπει να ταξινομεί τα προϊόντα του αλφαβητικά. Αυτό κάνει τα πράγματα πιο εύκολα στον εντοπισμό τους και βοηθά όταν υπάρχουν λάθη καταχώρισης, όπως το να υπάρχουν 'potatoes' και 'Potato' στη βάση δεδομένων.
Δημιούργησε τη συνάρτηση sort_entries(<cart>) που παίρνει ως όρισμα ένα καλάθι αγορών/λεξικό και επιστρέφει ένα νέο, ταξινομημένο αλφαβητικά.
>>> sort_entries({'Banana': 3, 'Apple': 2, 'Orange': 1})
{'Apple': 2, 'Banana':3, 'Orange': 1}
Η εφαρμογή πρέπει να στέλνει το καλάθι ενός δεδομένου χρήστη στο κατάστημα για εκτέλεση της παραγγελίας. Ωστόσο, οι υπάλληλοι του καταστήματος πρέπει να γνωρίζουν σε ποιον διάδρομο του καταστήματος βρίσκεται το προϊόν και αν αυτό χρειάζεται ψύξη. Έτσι (αρκετά αυθαίρετα) το "καλάθι εκτέλεσης" πρέπει να ταξινομείται σε αντίστροφη αλφαβητική σειρά, με τις ποσότητες των προϊόντων συνδυασμένες με πληροφορίες τοποθεσίας και ψύξης.
Δημιούργησε τη συνάρτηση send_to_store(<cart>, <aisle_mapping>) που παίρνει ένα καλάθι αγορών του χρήστη και ένα λεξικό που περιέχει τον αριθμό του διαδρόμου του καταστήματος και μια τιμή True/False για το αν κάθε προϊόν χρειάζεται ψύξη.
Η συνάρτηση θα πρέπει να επιστρέφει με return ένα συνδυασμένο "καλάθι εκτέλεσης" που περιέχει (ποσότητα, διάδρομο και ψύξη) για κάθε προϊόν που παραγγέλνει ο πελάτης.
Τα προϊόντα θα πρέπει να εμφανίζονται σε αντίστροφη αλφαβητική σειρά.
>>> send_to_store({'Banana': 3, 'Apple': 2, 'Orange': 1, 'Milk': 2},
{'Banana': ['Aisle 5', False], 'Apple': ['Aisle 4', False], 'Orange': ['Aisle 4', False], 'Milk': ['Aisle 2', True]})
{'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]}
Η εφαρμογή δεν μπορεί απλώς να καταχωρεί ατελείωτες παραγγελίες πελατών. Κάποια στιγμή, το κατάστημα θα ξεμείνει από διάφορα προϊόντα. Έτσι, το MVP της εφαρμογής σου πρέπει να ενημερώνει το απόθεμα του καταστήματος κάθε φορά που ένας χρήστης στέλνει την παραγγελία του στο κατάστημα. Διαφορετικά, οι πελάτες θα παραγγέλνουν προϊόντα που δεν είναι στην πραγματικότητα διαθέσιμα.
Δημιούργησε τη συνάρτηση update_store_inventory(<fulfillment_cart>, <store_inventory>) που παίρνει ένα "καλάθι εκτέλεσης" και ένα απόθεμα καταστήματος.
Η συνάρτηση θα πρέπει να μειώνει τις ποσότητες του αποθέματος του καταστήματος κατά τον αριθμό που έχει "παραγγελθεί" στο "καλάθι εκτέλεσης" και στη συνέχεια να επιστρέφει το ενημερωμένο απόθεμα του καταστήματος.
Όταν η ποσότητα ενός προϊόντος του καταστήματος πέφτει στο 0, η ποσότητα θα πρέπει να αντικαθίσταται από το μήνυμα "Out of Stock".
>>> update_store_inventory({'Orange': [1, 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True], 'Banana': [3, 'Aisle 5', False], 'Apple': [2, 'Aisle 4', False]},
{'Banana': [15, 'Aisle 5', False], 'Apple': [12, 'Aisle 4', False], 'Orange': [1, 'Aisle 4', False], 'Milk': [4, 'Aisle 2', True]})
{'Banana': [12, 'Aisle 5', False], 'Apple': [10, 'Aisle 4', False], 'Orange': ['Out of Stock', 'Aisle 4', False], 'Milk': [2, 'Aisle 2', True]}
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Python με 17 έννοιες146 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.