A Python dict osztálya számos hasznos metódust kínál a szótárakkal való munkához.
Néhányat már bemutattunk a dicts fogalomban.
Itt még néhányat átveszünk, valamint néhány technikát a szótárak bejárásához és módosításához.
setdefault() használata a hibamentes beszúráshozA szótár fogalomban korábban már szó volt róla, hogy a .get(key, <default value>) visszaadja a meglévő value-t, vagy a default value-t, ha egy key nem található a szótárban, így elkerülve a KeyError-t.
Ez jól működik olyan helyzetekben, amikor nem szeretnél külön hibakezelést, de nem bízhatsz abban, hogy a keresett key jelen lesz.
Hasonlóan „biztonságos” (KeyError nélküli) beszúráshoz használhatod a .setdefault(key, <default value>) metódust.
A setdefault(key, <default value>) visszaadja a value-t, ha a key megtalálható a szótárban.
Ha a kulcs nincs meg, akkor beszúrja a (key, default value) párt, és visszaadja a default value-t használatra.
>>> 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() használata szótár feltöltéséhez egy iterálható objektumbólHa gyorsan fel akarsz tölteni egy szótárt különféle keys-ekkel és alapértelmezett értékekkel, a osztálymetódus fromkeys(iterable, <default value>) végigmegy a keys egy iterálható halmazán, és létrehoz egy új dict-et.
Minden values a megadott default value-ra lesz állítva:
>>> 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'}
A .keys(), .values() és .items() metódusok a szótár iterálható nézeteit adják vissza.
Ezekkel a nézetekkel könnyedén végigmehetsz a bejegyzéseken anélkül, hogy módosítanád őket.
A nézetek emellett dinamikusak: amikor a mögöttes szótári adatok megváltoznak, a kapcsolódó view object tükrözni fogja a változást:
>>> 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() és .items() metódusokrólA Python 3.7+ verzióiban a dicts megőrzik a bejegyzések beszúrási sorrendjét, ami First-in, First-out (FIFO) bejárást tesz lehetővé a .keys(), .values() vagy .items() használatakor.
A Python 3.8+ verzióiban a nézetek megfordíthatók is.
Ez lehetővé teszi, hogy a kulcsokat, értékeket vagy (key, value) párokat Last-in, First-out (LIFO) sorrendben járjuk be a reversed(<dict>.keys()), reversed(<dict>.values()) vagy reversed(<dict>.items()) segítségével:
>>> 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')
A szótáraknak nincs beépített rendezési metódusuk.
Viszont egy dict nézet rendezhető a beépített sorted() függvénnyel és a dict.items() metódussal.
A rendezett nézet ezután felhasználható egy új szótár létrehozásához.
A bejáráshoz hasonlóan az alapértelmezett rendezés a szótár keys szerint történik.
# 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() metódussalA <dict_one>.update(<dict_two>) két szótár összefésülésére használható.
Ez a metódus veszi a <dict_two> (key,value) párjait, és beírja őket a <dict_one>-ba:
>>> 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'}
Ahol a két szótár kulcsai átfedésben vannak, a dict_one value-ját felülírja a dict_two megfelelő value-ja:
>>> 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'}
| és |=) operátorokkalA Python 3.9 egy másik módot vezet be a dicts egyesítésére: a union operátorokat.
A dict_one | dict_two egy új szótárat hoz létre, amely a dict_one és dict_two (key, value) párjaiból áll.
Amikor mindkét szótár osztozik kulcsokon, a dict_two értékei élveznek elsőbbséget.
>>> 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'}
A dict_one |= other hasonlóan viselkedik, mint a <dict_one>.update(<other>), de ebben az esetben az other lehet dict vagy (key, value) párok iterálható halmaza:
>>> 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'}
A szótárak és a velük való munkához használt metódusok részletes leírásához a hivatalos útmutató és a hivatalos könyvtári referencia kiváló kiindulópont.
A Real Python és a Finxter is nagyon részletes cikkekkel rendelkezik a Python szótárakról.
A Mecha Munch™, egy élelmiszerbevásárlást automatizáló cég, épp most vett fel, hogy a rendelési alkalmazásukon dolgozz. A csapatod feladata, hogy elkészítsen egy MVP-t (minimálisan működőképes termék), amely a bevásárlókosár minden alapvető műveletét kezeli, így a felhasználók hozzáadhatják, eltávolíthatják és rendezhetik a bevásárlásaikat. Szerencsére a pénzzel és a fizetéssel kapcsolatos funkciókat egy másik csapat kezeli!
Az MVP tegye lehetővé, hogy a felhasználó tételeket adjon a bevásárlókosarához. Ez lehet egyetlen tétel vagy egyszerre több tétel is. Mivel ez egy MVP, a tétel mennyiségét az ismétlődések jelzik. Ha a felhasználó 2 Oranges-t szeretne hozzáadni, az 'Oranges' kétszer fog szerepelni a bemeneti iterálhatóban. Ha a felhasználó kosarában már szerepel a tétel, a kosárban lévő mennyiséget 1-gyel kell növelni. Ha a tétel új a kosárban, akkor 1-es mennyiséggel kell hozzáadni.
Hozd létre az add_item(<current_cart>, <items_to_add>) függvényt, amely argumentumként egy kosárszótárat és bármilyen lista jellegű, hozzáadandó tételekből álló iterálhatót fogad.
A függvény adjon vissza egy új/frissített bevásárlókosár-szótárat a felhasználónak.
>>> 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}
Hoppá. Úgy tűnik, a termékcsapat funkciótúltengésbe kezdett. Extra funkciókat szeretnének hozzáadni az MVP-hez. Az alkalmazásnak mostantól úgy kell bevásárlókosarat létrehoznia, hogy beolvassa a tételeket a felhasználó jegyzetalkalmazásából. Kényelmes a felhasználóknak, de kicsit több munka a csapatnak.
Hozd létre a read_notes(<notes>) függvényt, amely argumentumként bármilyen lista jellegű iterálhatót elfogad.
A függvény dolgozza fel a tételeket, és hozzon létre egy felhasználói bevásárlókosarat/szótárat.
Minden tételt 1-es mennyiséggel kell hozzáadni.
Ezután az új felhasználói kosarat kell visszaadni.
>>> 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}
Az alkalmazásnak van egy „ötletek” szakasza, amely különféle konyhákból származó elkészült receptekkel van tele. A felhasználó kiválaszthatja ezek közül bármelyiket, és annak minden hozzávalója automatikusan a bevásárlókosarába kerül. A projektmenedzser megkért, hogy hozz létre egy módot ezeknek az „ötletek” recepteknek a szerkesztésére, mivel a tartalomcsapat folyamatosan változtatja a hozzávalókat és a mennyiségeket.
Hozd létre az update_recipes(<ideas>, <recipe_updates>) függvényt, amely argumentumként egy „ötletek” szótárat és egy receptfrissítésekből álló iterálhatót fogad.
A függvény adja vissza az új/frissített „ötletek” szótárat.
>>>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}}
Miután a felhasználó elkezdett egy kosarat, az alkalmazás lehetővé teszi számára, hogy ábécésorrendbe rendezze a tételeit. Ez megkönnyíti a dolgok megtalálását, és segít az olyan adatbeviteli hibák esetén, mint amikor 'potatoes' és 'Potato' is szerepel az adatbázisban.
Hozd létre a sort_entries(<cart>) függvényt, amely argumentumként egy bevásárlókosarat/szótárat fogad, és visszaad egy új, ábécésorrendbe rendezettet.
>>> sort_entries({'Banana': 3, 'Apple': 2, 'Orange': 1})
{'Apple': 2, 'Banana':3, 'Orange': 1}
Az alkalmazásnak el kell küldenie egy adott felhasználó kosarát a boltba teljesítésre. A bolt dolgozóinak azonban tudniuk kell, hogy a tétel melyik folyosón található, és hogy szükséges-e hűtés. Tehát (meglehetősen önkényesen) a „teljesítési kosarat” fordított ábécésorrendbe kell rendezni, a tételmennyiségeket pedig a helyszínre és a hűtésre vonatkozó információval együtt kell megadni.
Hozd létre a send_to_store(<cart>, <aisle_mapping>) függvényt, amely egy felhasználói bevásárlókosarat és egy szótárat fogad, amely minden tételhez tartalmazza a bolti folyosó számát és egy True/False értéket arról, hogy szükséges-e hűtés.
A függvény return-nel adjon vissza egy összevont „teljesítési kosarat”, amely minden egyes megrendelt tételhez tartalmazza a mennyiséget, a folyosót és a hűtést.
A tételek fordított ábécésorrendben jelenjenek meg.
>>> 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]}
Az alkalmazás nem adhat le vég nélkül vásárlói rendeléseket. Előbb-utóbb a boltból elfogynak a különféle termékek. Ezért az MVP-alkalmazásodnak frissítenie kell a bolti készletet minden alkalommal, amikor egy felhasználó elküldi a rendelését a boltba. Különben a vásárlók olyan termékeket rendelnek, amelyek valójában nem elérhetők.
Hozd létre az update_store_inventory(<fulfillment_cart>, <store_inventory>) függvényt, amely egy „teljesítési kosarat” és egy bolti készletet fogad.
A függvény csökkentse a bolti készlet mennyiségeit a „teljesítési kosárban” szereplő „megrendelt” számmal, majd adja vissza a frissített bolti készletet.
Ahol egy bolti tétel darabszáma 0-ra csökken, ott a darabszámot a 'Out of Stock' üzenettel kell helyettesíteni.
>>> 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]}
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Python nyelvet 17 fogalom146 feladat segítségével, valódi emberi mentorálással, mindez ingyen.