Working with Lists and Sequences
The general strategy is to scan the sequence from beginning to end while carrying one piece of state: the largest or smallest value found so far.
Finding Extremes Step by Step
Many programs need to find an extreme value in a collection: the highest temperature, the lowest price, or the maximum heart rate recorded during a workout. The general strategy is to scan the sequence from beginning to end while carrying one piece of state: the largest or smallest value found so far.
The Largest-So-Far Pattern
For a maximum search, keep a variable named largest that represents the largest value encountered up to the current point in the loop. For every item, update largest only when the item is strictly larger than the stored value. The condition uses two parts: largest is None handles initialization, and itervar > largest handles later comparisons.
values = [4, 9, 6, 2]
largest = None
for itervar in values:
if largest is None or itervar > largest:
largest = itervar
print(largest)- 1largest begins as None, which marks that no value has been stored yet.
- 2The first item, 4, satisfies largest is None, so largest becomes 4.
- 3The next item, 9, is greater than 4, so largest becomes 9.
- 4The item 6 is not greater than 9, so largest remains 9.
- 5The item 2 is not greater than 9, so largest remains 9.
- 6The printed result is 9.
9The Smallest-So-Far Pattern
The minimum pattern has the same structure as the maximum pattern. The variable smallest stores the smallest value found so far. The initialization test is still smallest is None, but the comparison changes from greater than to less than: if smallest is None or itervar < smallest. The stored value changes only when a strictly smaller item is encountered.
Tracking the Minimum
Find the smallest value in the sequence 8, 3, 5, and 1.
- 1Start
Set smallest to None because no sequence item has been examined yet.
- 2Read 8
smallest is None, so store 8 as the first smallest-so-far value.
- 3Read 3
3 is less than 8, so replace smallest with 3.
- 4Read 5
5 is not less than 3, so keep 3.
- 5Read 1
1 is less than 3, so replace smallest with 1.
The smallest-so-far value is 1.
Why None Starts the Search
None is used to mark the extreme variable as empty before the loop has processed any item. It is not a candidate maximum or minimum. Instead, it tells the first loop iteration that an actual sequence value must be stored.
Manual Loops and Built-ins
| Approach | What it does | When to use it |
|---|---|---|
| Manual loop | Compares each item and maintains an extreme value | Learning the algorithm, debugging, or working in a language without a built-in extreme function |
| max() | Finds the maximum value in a sequence | Real-world Python code when the maximum result is all that is needed |
| min() | Finds the minimum value in a sequence | Real-world Python code when the minimum result is all that is needed |
Manual loops expose the algorithm; max() and min() provide direct built-in operations.
9
2In practical Python code, use max() or min() when you simply need the extreme value. The source material describes these functions as more concise, faster, and less error-prone than writing the loop yourself. Study the manual pattern anyway: it reveals the underlying algorithm, helps with debugging, and transfers to languages that do not provide built-in extreme functions.
Mistakes in Extreme Searches
Common mistake Starting largest or smallest with an arbitrary number.
What it looks likelargest = 0Why it failsThe chosen number may not be appropriate for every sequence, and it does not represent the fact that no item has been processed yet.
Do this insteadInitialize the variable to None and let the first item establish the starting extreme.
Common mistake Using the wrong comparison operator.
What it looks likeif smallest is None or itervar > smallest:Why it failsThe greater-than operator searches for larger values, not smaller ones.
Do this insteadUse itervar < smallest for the smallest-so-far pattern.
Common mistake Updating the extreme on every iteration.
What it looks likelargest = itervarWhy it failsThe variable would become the most recently processed item rather than the largest item seen so far.
Do this insteadUpdate only when largest is None or itervar > largest.
Common mistake Forgetting the None initialization check.
What it looks likeif itervar > largest:Why it failsBefore the first item is stored, largest has no sequence value to compare against.
Do this insteadInclude largest is None or before the comparison.
Practice the State Trace
What do you think happens?
For the sequence [5, 2, 11, 7], what are the successive values of largest after each item is processed?
Reveal answer
5, 5, 11, 11
The first item initializes largest to 5. The value 2 is not larger, 11 replaces 5, and 7 is not larger than 11.
Write a manual loop that finds the smallest value in the sequence [14, 6, 9, 2]. Then trace the value of smallest after each item is processed.
Hints
- Start with smallest = None.
- Use the condition smallest is None or itervar < smallest.
- The state should change only when the current item is smaller than the stored value.
Key Takeaways
- 1An extreme-finding loop carries the largest or smallest value found so far.
- 2Initialize the extreme variable to None to represent an empty result before the first item is processed.
- 3For maximum searches, update when itervar > largest; for minimum searches, update when itervar < smallest.
- 4The extreme variable changes only when the current item is strictly more extreme than the stored value.
- 5Use
max()andmin()in practical Python code when you need the result directly, but understand the manual loop to learn the algorithm and debug it.
At a glance
- Use a largest-so-far or smallest-so-far variable while scanning a sequence.
- Use None to show that no sequence value has been stored yet.
- The maximum pattern uses >, while the minimum pattern uses <.
- Trace the stored state after every item to understand and debug the loop.
- Prefer
max()andmin()for direct results in practical Python code.