Dictionaries en andere verzamelingen · oefening
Doorzoek een lijst met records
Een catalogus is nuttig wanneer een programma één record via een veld kan vinden.
catalog = [
{"title": "Kindred", "year": 1979},
{"title": "Dune", "year": 1965},
]
Je kunt de lijst niet om "Dune" als sleutel vragen. De lijst bevat dictionaries, dus doorzoek de records één voor één:
for item in catalog:
if item["title"] == "Dune":
print(item)
Zet het zoeken in een functie
Een zoekfunctie kan de overeenkomende dictionary teruggeven:
def find_by_title(catalog, query):
for item in catalog:
if item["title"] == query:
return item
return None
Als een titel overeenkomt, beëindigt de eerste return de functie direct en stuurt die dictionary naar de aanroeper.
Als de lus eindigt zonder overeenkomst, bereikt de uitvoering return None. None maakt “geen overeenkomend record” expliciet.
Hoofdstuk 8 liet al zien dat return de huidige functieaanroep beëindigt en dat een functie zonder bruikbaar resultaat None oplevert. Hier wordt dat gedrag onderdeel van de afspraak voor een zoekopdracht:
een overeenkomst geeft een dictionary terug;
geen overeenkomst geeft
Noneterug.
De twee paden hieronder laten zien waarom de laatste return None na de lus hoort: een overeenkomst leidt tot een vroege terugkeer, terwijl voor een ontbrekende zoekterm eerst elk record bekeken moet worden. “Matching query” is een zoekterm met een overeenkomst, “Missing query” een zoekterm zonder overeenkomst. “No” betekent geen overeenkomst en “Match” betekent wel een overeenkomst. “Return record” geeft het record terug; “Return None” geeft de speciale waarde terug die aangeeft dat er niets is gevonden.

Schoon beide kanten op
Mensen kunnen andere hoofdletters of spaties aan de buitenkant typen. Schoon de zoekterm één keer op:
clean_query = query.strip().lower()
Voeg die opschoning toe aan de volledige functie en vergelijk met een versie van elke opgeslagen titel in kleine letters:
def find_by_title(catalog, query):
clean_query = query.strip().lower()
for item in catalog:
if item["title"].lower() == clean_query:
return item
return None
De oorspronkelijke titel in de dictionary blijft ongewijzigd.
Controleer het resultaat
Gebruik is not None wanneer er een overeenkomst is gevonden:
match = find_by_title(catalog, " DUNE ")
if match is not None:
print(match["year"])
else:
print("No matching title.")
is None en is not None zijn de standaardcontroles voor deze ene speciale waarde.
Wat bevat match?
def find_by_name(records, query):
for record in records:
if record["name"].lower() == query.strip().lower():
return record
return None
places = [
{"name": "Kyoto", "country": "Japan"},
{"name": "Lima", "country": "Peru"},
]
match = find_by_name(places, " lima ")
Opdracht
Maak find_by_title(catalog, query) af.
De functie moet:
queryopschonen met.strip().lower();de dictionaryrecords in
catalogdoorlopen;de opgeschoonde zoekterm vergelijken met elke titel in kleine letters;
de overeenkomende dictionary direct teruggeven;
na de lus
Noneteruggeven als niets overeenkwam.
Behoud de bestaande aanroep en resultaatcontrole.
Verwachte uitvoer:
Found: Dune (1965)
De beoordelaar roept je functie ook aan met een andere titel en met een ontbrekende titel.