Course contents
On this page
Build the first lookup in memory
Walk through a short program that finds product 27, including the missing-product case.
We have asked SQL to find a product. Now we will implement the search directly. Start with three records in the working memory of a running program. This is small enough to inspect without a storage library or a database server.
The following Python example is complete. Python is used to make the mechanism readable; it does not choose the implementation language for our eventual engine.
products = [
{"product_id": 12, "name": "Notebook"},
{"product_id": 27, "name": "Canvas tote"},
{"product_id": 46, "name": "Desk lamp"},
]
def find_product(rows, wanted_id):
for row in rows:
if row["product_id"] == wanted_id:
return row
return None
assert find_product(products, 27)["name"] == "Canvas tote"
assert find_product(products, 99) is NoneRead the program one decision at a time
The outer square brackets hold a list. Each pair of braces holds a record with named fields. row["product_id"] reads that field from the current record.
def introduces a function: a named operation we can call with different inputs. Here its inputs are a collection of rows and the product number we want. The loop visits one row at a time. == tests equality. return finishes the function and supplies its answer.
- Inspect product 12
12 does not equal 27. Continue.
- Inspect product 27
27 equals 27. Return the Canvas tote record.
- Product 46 is not inspected
The function has already returned.
None represents “no matching record” here. It is our function’s missing-result signal, not a SQL row containing NULL. A caller must check that signal before reading fields from the result.
The two assert lines are executable checks. They stop with an error if the result differs from our expectation. One checks a present product; the other checks an absent product. They do not prove all behavior, but they exercise two different paths.
State what this tiny function assumes
Our input has distinct product IDs and correctly shaped records. The function does not enforce those rules itself. If the list contains two records with ID 27, it returns the first one. A real table needs insertion logic that checks the key rule before accepting a duplicate.
The returned object is also the existing record, not a protected copy. Other code could change it directly. That is acceptable for this trace; it would be a poor boundary for enforcing transactions.
Try the missing case by hand
How many rows does a lookup for product 99 inspect? What happens with an empty list?
Follow the loop to its end
For 99, all three comparisons fail, so the loop finishes and the function returns None. With an empty list, the loop body never runs; execution goes straight to the same missing-result return.
The final return is necessary. A successful lookup alone would not have shown whether the function handles absence deliberately.
We have an understandable read operation. Before making it faster, we need to preserve its records after the program stops. The next stage turns those records into bytes that a file can store.
Further reading
Python’s introduction to control flow explains loops and functions. For algorithm foundations, the MIT 6.006 notes cover data structures and the work their operations perform.