0%

Dictionaries and Other Collections · practice

Search a List of Records

A catalog is useful when a program can find one record by a field.

catalog = [
    {"title": "Kindred", "year": 1979},
    {"title": "Dune", "year": 1965},
]

You cannot ask the for "Dune" as a key. The list holds , so search one record at a time:

for item in catalog:
    if item["title"] == "Dune":
        print(item)

Put the search in a function

A search can return the matching dictionary:

def find_by_title(catalog, query):
    for item in catalog:
        if item["title"] == query:
            return item

    return None

If a title matches, the first ends the function immediately and sends that dictionary to the caller.

If the finishes without a match, execution reaches return None. None makes “no matching record” explicit.

Chapter 8 already showed that return ends the current function call and that a function without a useful result produces None. Here, that behavior becomes part of a search contract:

  • a match returns a dictionary;

  • no match returns None.

The two paths below show why the final return None belongs after the loop: a match exits early, while a missing query must inspect every record first.

Two search paths compare records in order; Dune returns its matching record immediately, while Solaris reaches the end and returns None.

Clean both sides

People may type different capitalization or surrounding spaces. Clean the query once:

clean_query = query.strip().lower()

Put that cleaning into the complete function and compare it with a lowercase version of each stored title:

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

The original title in the dictionary stays unchanged.

Check the result

Use is not None when a match was found:

match = find_by_title(catalog, "  DUNE ")

if match is not None:
    print(match["year"])
else:
    print("No matching title.")

is None and is not None are the standard checks for this one special .

What does match contain?

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 ")

Task

Complete find_by_title(catalog, query).

The must:

  1. clean query with .strip().lower();

  2. through the records in catalog;

  3. compare the cleaned query with each lowercase title;

  4. return the matching dictionary immediately;

  5. return None after the loop if nothing matched.

Keep the existing call and result check.

Expected output:

Found: Dune (1965)

The grader also calls your function with another title and with a missing title.