Concepts / Working with Lists and Sequences

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.

  • Programming

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.

Sequence7, 3, 10, 67current item7current extreme3current item7current extreme10current item10current extremenext iteminitializecarry statecomparecarry statereplace
How does the loop move through a sequence while carrying the current extreme value forward?

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.

Nonelargest4first item4largest9next item9largest6next item9largestprocessfirst item becomes largestcompare9 > 4compare6 is not larger
How does each sequence value compare with the largest value found so far, and when is the stored maximum replaced?
Code walkthrough
values = [4, 9, 6, 2]
largest = None

for itervar in values:
    if largest is None or itervar > largest:
        largest = itervar

print(largest)
  1. 1
    largest begins as None, which marks that no value has been stored yet.
  2. 2
    The first item, 4, satisfies largest is None, so largest becomes 4.
  3. 3
    The next item, 9, is greater than 4, so largest becomes 9.
  4. 4
    The item 6 is not greater than 9, so largest remains 9.
  5. 5
    The item 2 is not greater than 9, so largest remains 9.
  6. 6
    The printed result is 9.
Output
9

The 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.

Nonesmallest8first item8smallest3next item3smallest5next item3smallestprocessfirst item becomes smallestcompare3 < 8compare5 is not smaller
How does each sequence value compare with the smallest value found so far, and when is the stored minimum replaced?
Worked example

Tracking the Minimum

Find the smallest value in the sequence 8, 3, 5, and 1.

  1. 1
    Start

    Set smallest to None because no sequence item has been examined yet.

  2. 2
    Read 8

    smallest is None, so store 8 as the first smallest-so-far value.

  3. 3
    Read 3

    3 is less than 8, so replace smallest with 3.

  4. 4
    Read 5

    5 is not less than 3, so keep 3.

  5. 5
    Read 1

    1 is less than 3, so replace smallest with 1.

Result

The smallest-so-far value is 1.

Why None Starts the Search

Definition

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.

Noneno value stored12first item12first extremeloop readsinitialize
How does initializing the extreme variable to None represent an empty result, and how does the first item change that state?

Manual Loops and Built-ins

ApproachWhat it doesWhen to use it
Manual loopCompares each item and maintains an extreme valueLearning the algorithm, debugging, or working in a language without a built-in extreme function
max()Finds the maximum value in a sequenceReal-world Python code when the maximum result is all that is needed
min()Finds the minimum value in a sequenceReal-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.

python
Output
9
2

In 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 like
    largest = 0
    Why it fails

    The 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 instead

    Initialize the variable to None and let the first item establish the starting extreme.

  • Common mistake

    Using the wrong comparison operator.

    What it looks like
    if smallest is None or itervar > smallest:
    Why it fails

    The greater-than operator searches for larger values, not smaller ones.

    Do this instead

    Use itervar < smallest for the smallest-so-far pattern.

  • Common mistake

    Updating the extreme on every iteration.

    What it looks like
    largest = itervar
    Why it fails

    The variable would become the most recently processed item rather than the largest item seen so far.

    Do this instead

    Update only when largest is None or itervar > largest.

  • Common mistake

    Forgetting the None initialization check.

    What it looks like
    if itervar > largest:
    Why it fails

    Before the first item is stored, largest has no sequence value to compare against.

    Do this instead

    Include 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?

  • 5, 2, 11, 7

  • 5, 5, 11, 11

  • None, 5, 5, 11

  • 11, 11, 11, 11

Reveal answer
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.

MEDIUM

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

  1. 1
    An extreme-finding loop carries the largest or smallest value found so far.
  2. 2
    Initialize the extreme variable to None to represent an empty result before the first item is processed.
  3. 3
    For maximum searches, update when itervar > largest; for minimum searches, update when itervar < smallest.
  4. 4
    The extreme variable changes only when the current item is strictly more extreme than the stored value.
  5. 5
    Use max() and min() 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() and min() for direct results in practical Python code.

Related concepts

More concepts starting with W