Building Memory in Loops

Introduction: Remembering Something Across Iterations

Welcome back to Iterating with For Loops in Python!

So far, our loop iterations have mostly been independent. We printed a fruit, printed a number, or printed an index. Each iteration performed its action and moved on.

Real questions often require the loop to remember earlier work:

  • What is the total of these scores?
  • How many scores did we visit?
  • What is their average?
  • What is the product of several factors?

Consider this list:

scores = [88, 92, 79, 95, 84]

By the end of this lesson, we will turn that list into a total, a count, and an average. We will also use a similar pattern to build a product.

The two key patterns are the accumulator and the counter.

The Accumulator Pattern: Initialize, Then Update

Every accumulation has the same two-part shape:

  1. Create a variable before the loop.
  2. Update that variable inside the loop.

Here is an accumulator that builds a total:

scores = [88, 92, 79, 95, 84]

total = 0

for score in scores:
    total += score

Two lines deserve a closer look:

  • total = 0 is outside the loop because it creates the starting value only once.
  • total += score is inside the loop because every score should contribute to the total.

The line:

total += score

is shorthand for:

total = total + score

Python reads the old value of total, adds the current score, and stores the result back in total.

The variable survives between iterations, so each update builds on the work of the previous one.

Tracing the Total Iteration by Iteration

Let's watch the accumulator change:

Iterationscoretotal beforetotal after
188088
29288180
379180259
495259354
584354438

If we temporarily print total inside the loop, we see the running totals:

88
180
259
354
438

Only the final value answers the question about the complete total. Therefore, the real summary print belongs after the loop:

print("Total:", total)

The Counter Pattern: Adding One Instead of the Item

A counter uses the same structure, but it adds a fixed 1 instead of adding the current item's value:

count = 0

for _ in scores:
    count += 1

The underscore _ means that the current item is deliberately ignored. The loop still runs once per score, but the score's value is not needed for this particular job.

The counter changes like this:

0 → 1 → 2 → 3 → 4 → 5

It finishes at 5.

We could write a descriptive loop variable:

for score in scores:
    count += 1

That is valid Python, but score is not read inside the body. Using _ clearly communicates that only the number of iterations matters.

For this list, len(scores) would provide the count more directly. The loop-based counter becomes especially useful when we want to count only items that satisfy a condition, which we will do in Unit 4.

Maintaining a Total and Count in One Loop

A loop body can update more than one variable. Because each score contributes to both the total and the count, we can maintain both values in a single pass:

scores = [88, 92, 79, 95, 84]

total = 0
count = 0

for score in scores:
    total += score
    count += 1

On each iteration:

  • total grows by the current score;
  • count grows by 1.

This single-loop version avoids walking through the same list twice and keeps the related updates together.

Iterationscoretotal aftercount after
188881
2921802
3792593
4953544
5844385

Computing the Average

After the loop, both values are final:

average = total / count

print("Total:", total)
print("Count:", count)
print("Average:", average)

The average is computed after the loop because it needs the completed total and count.

The / operator produces a floating-point result, so 438 / 5 gives 87.6.

Total: 438
Count: 5
Average: 87.6

There is one important caution: if scores is empty, count stays at 0. Dividing by zero raises a ZeroDivisionError.

Because you already know if and else, you could protect the calculation like this:

if count > 0:
    average = total / count
    print("Average:", average)
else:
    print("No scores to average")

The examples in this unit use nonempty lists, so the regular division is safe.

Changing the Starting Value: Building a Product

The starting value must match the operation.

For addition, we start at 0 because adding zero does not change a number.

For multiplication, we start at 1 because multiplying by one does not change a number:

factors = [2, 3, 5, 4]

product = 1

for factor in factors:
    product *= factor

The line:

product *= factor

is shorthand for:

product = product * factor

Here is the product trace:

Iterationfactorproduct beforeproduct after
1212
2326
35630
4430120

Starting at 0 would not work:

product = 0

Every multiplication would remain zero because zero multiplied by any number is zero.

The general rule is to choose a starting value that does not change the first item when the operation is applied:

  • 0 for addition;
  • 1 for multiplication.

Full Program and Output

Here are all the pieces assembled into one program:

scores = [88, 92, 79, 95, 84]

total = 0
count = 0

for score in scores:
    total += score
    count += 1

average = total / count

factors = [2, 3, 5, 4]
product = 1

for factor in factors:
    product *= factor

print("Total:", total)
print("Count:", count)
print("Average:", average)
print("Product:", product)

Output:

Total: 438
Count: 5
Average: 87.6
Product: 120

Common Pitfalls with Counters and Accumulators

These mistakes account for many broken accumulators:

  • Initializing inside the loop: placing total = 0 inside the body resets the value during every iteration.
  • Forgetting to initialize: total += score fails if total does not already exist.
  • Using = instead of +=: total = score replaces the old value instead of adding to it.
  • Printing inside the loop by accident: this displays partial results rather than one final result.
  • Using the wrong starting value: a product that starts at 0 remains 0.
  • Dividing by zero: an empty list leaves the count at 0.
  • Walking through the same data unnecessarily: when every item contributes to multiple results, those variables can often be updated in one loop.

When an accumulator produces a surprising answer, trace its value through the first two iterations.

Conclusion and Next Steps

Three ideas to carry forward:

  • Initialize the variable before the loop, update it inside the loop, and use the finished result after the loop.
  • Counters add a fixed 1, while sum accumulators add each item's value.
  • Choose the correct starting value: 0 for addition and 1 for multiplication.

A single loop can maintain several related values at the same time. This lets us calculate a total and count together before using both to compute an average.

Coming up in Unit 4, an if inside the loop will let us total and count only the items that match a condition. First, the practice tasks are ready: build a total, count without len(), calculate an average in one pass, and grow a product from 1.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal