Lists and Records
Min and Max Scan
Find the smallest and largest values in a list in a single pass. Seeding the running bounds from the first element avoids sentinel values; the trace shows exactly when each bound tightens.
By hand
Seed lo and hi from values[0] so no sentinel (0, float('inf')) is
needed. Then scan the rest: lower the floor when a new minimum appears, raise
the ceiling when a new maximum appears.
naive.py
Replay: real traced execution (multi-file project)
values = [5, 2, 8, 1, 9, 3, 7, 4]
lo = values[0]
hi = values[0]
for v in values[1:]:
if v < lo:
lo = v
if v > hi:
hi = v
print('RESULT:', (lo, hi))
values ← [5, 2, 8, 1, 9, 3, 7, 4]
1values = [5, 2, 8, 1, 9, 3, 7, 4]2lo = values[0]values this step[5, 2, 8, 1, 9, 3, 7, 4]valueslo ← 5
1values = [5, 2, 8, 1, 9, 3, 7, 4]2lo = values[0]3hi = values[0]values this step5lohi ← 5
2lo = values[0]3hi = values[0]4for v in values[1:]:values this step5hiv ← 2
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step2vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vlo ← 2
5if v < lo:6 lo = v7if v > hi:values this step5 → 2loif v > hi:
6 lo = v7if v > hi:8 hi = vv ← 8
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step2 → 8vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vif v > hi:
6 lo = v7if v > hi:8 hi = vhi ← 8
7 if v > hi:8 hi = v9print('RESULT:', (lo, hi))values this step5 → 8hiv ← 1
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step8 → 1vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vlo ← 1
5if v < lo:6 lo = v7if v > hi:values this step2 → 1loif v > hi:
6 lo = v7if v > hi:8 hi = vv ← 9
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step1 → 9vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vif v > hi:
6 lo = v7if v > hi:8 hi = vhi ← 9
7 if v > hi:8 hi = v9print('RESULT:', (lo, hi))values this step8 → 9hiv ← 3
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step9 → 3vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vif v > hi:
6 lo = v7if v > hi:8 hi = vv ← 7
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step3 → 7vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vif v > hi:
6 lo = v7if v > hi:8 hi = vv ← 4
3hi = values[0]4for v in values[1:]:5 if v < lo:values this step7 → 4vif v < lo:
4for v in values[1:]:5 if v < lo:6 lo = vif v > hi:
6 lo = v7if v > hi:8 hi = vfor v in values[1:]:
3hi = values[0]4for v in values[1:]:5 if v < lo:stdout ← RESULT: (1, 9)
8 hi = v9print('RESULT:', (lo, hi))values this stepRESULT: (1, 9)stdout
The Pythonic way
The built-ins min and max each walk the list once internally in C.
Two calls over eight values is negligible, and the intent is unambiguous.
library.py
values = [5, 2, 8, 1, 9, 3, 7, 4]
lo = min(values)
hi = max(values)
print('RESULT:', (lo, hi))
RESULT: (1, 9)
Implementation notes
- Seeding from
values[0]is correct for any non-empty list of any comparable type; a sentinel like0orfloat('inf')would require assumptions about the data range. - In this run
lotightens twice (5→2→1) andhirises twice (5→8→9); both progressions are visible in the trace.