LambdaLabTM
Computer Science · Class 11 · Lists Revisited
ListsThe short form⏱️ 14 min read

Traversal by Item

for m in marks: — the form to reach for whenever the program only reads the list. It cannot change one, and most programs do not need to: they add the items up, count the ones that pass a test, look for the biggest, or build a second list beside the first.

1The four collectors, and that is most of it

Total
total = 0

Adds each item. Zero is the value that changes nothing.

Count
count = 0

Goes up by 1 when the item passes a test — by 1, not by the item.

Champion
best = marks[0]

The best seen so far. Starts as a real member of the list.

New list
result = []

Grows by append(). The original is never touched.

2Program 1 — the total and the average

📋 The problem

Add up a list of marks and print the class average — without sum().

total_average.py
# the total and the average, without sum()

marks = [72, 65, 88, 91, 54]
total = 0

for m in marks:
    total = total + m

print('Total:', total)
print('Average:', total / len(marks))
Output
Total: 370
Average: 74.0
total = 0

Above the loop, so it is made once and survives every round. Inside the loop it would be wiped each time and the answer would be the last mark.

total = total + m

The right-hand side is worked out first — the old total plus this round's mark — and the answer goes back into the same box.

print('Average:', total / len(marks))

After the loop, and divided by len(marks) rather than by 5, so adding a sixth mark to the list needs no other change.

Tip
Python has sum(marks) and len(marks). sum(marks) / len(marks) is the whole program in one line, and it is what you would write in real code. The loop is what the question is testing — and it is the one that keeps working the moment the rule gets fussier, as it does in program 5.

3Program 2 — how many even, how many odd?

📋 The problem

Count the even and the odd numbers in a list.

evens_odds.py
# how many even numbers, and how many odd?

numbers = [12, 7, 30, 45, 8, 21, 64]
evens = 0
odds = 0

for n in numbers:
    if n % 2 == 0:
        evens = evens + 1
    else:
        odds = odds + 1

print('Even numbers:', evens)
print('Odd numbers:', odds)
Output
Even numbers: 4
Odd numbers: 3

Two counters, one if…else, and the check that the program is right: 4 + 3 = 7, which is len(numbers). Every item landed in exactly one of the two, which is what an else guarantees and two separate ifs would not.

Watch Out
evens = evens + 1, not evens = evens + n. A counter goes up by one per item; a total goes up by the item. Mixing them up is the commonest slip on this page, and the answer it produces — 114 “even numbers” — is obviously wrong only if you look.

4Program 3 — the largest and the smallest

📋 The problem

Find the highest and lowest mark in a list, without max() or min().

largest_smallest.py
# the largest and the smallest, without max() and min()

marks = [56, 91, 43, 78, 65]
largest = marks[0]
smallest = marks[0]

for m in marks:
    if m > largest:
        largest = m

    if m < smallest:
        smallest = m

print('Largest:', largest)
print('Smallest:', smallest)
Output
Largest: 91
Smallest: 43
Key Takeaway
Both champions start at marks[0]. Not at 0, and not at 100. A champion has to start as a real member of the list, or it can win: start largest at 0 and a list of negative temperatures reports a highest of 0, which is not in the list at all. Starting at marks[0] can never be wrong, because that value really is one of the candidates.

Two separate ifs, not if…elif: both questions must be asked of every mark. With an elif, a mark that beat the largest would never be tested against the smallest — harmless here, and exactly the kind of thing that is not harmless later.

5Program 4 — a new list of squares

📋 The problem

Build a second list holding the square of every number in the first, and show that the original is untouched.

squares.py
# a new list holding the square of every number

numbers = [2, 5, 7, 10]
squares = []

for n in numbers:
    squares.append(n * n)

print('Original:', numbers)
print('Squares: ', squares)
Output
Original: [2, 5, 7, 10]
Squares:  [4, 25, 49, 100]
squares = []

An empty list, made before the loop. It is the same collector idea as total = 0 — the value that means 'nothing yet' for a list is [].

squares.append(n * n)

append() adds one item to the end. It changes squares and hands back nothing, which is why it is never written as squares = squares.append(...) — that would put None where the list was.

Watch Out
squares = squares.append(n * n) destroys the list. append() is one of the methods that changes the list rather than answering with a new one, so it returns None — and assigning that back puts None in squares. The very next round then fails with AttributeError: 'NoneType' object has no attribute 'append'.
squares.py

6Program 5 — how many are above the average?

📋 The problem

Work out the class average, then count how many marks beat it.

above_average.py
# how many marks are above the class average?

marks = [72, 65, 88, 91, 54]
total = 0

for m in marks:
    total = total + m

average = total / len(marks)
count = 0

for m in marks:
    if m > average:
        count = count + 1

print('Average:', average)
print('Above average:', count)
Output
Average: 74.0
Above average: 2
Key Takeaway
Two loops, and it has to be two. The average is not known until every mark has been added, so nothing can be compared with it during the first pass. Any question of the form “how many are above the average / longer than the mean / better than the rest” is a two-pass program: work the summary out, then walk the list again with it.

This is also where sum() stops rescuing you. The first loop could be total = sum(marks), but the second one has no built-in at all — there is no function for “count the items above this number”.

7Recap

Collector above, work inside, print after

0 for a total, 0 for a count, marks[0] for a champion, [] for a new list. All four are made before the loop starts.

A counter goes up by 1

A total goes up by the item. They look alike and they answer different questions.

A champion starts inside the list

marks[0] is always safe. A made-up starting value like 0 or 100 can win, and then the answer is not in the list.

append() changes the list and returns None

Write squares.append(x) on its own line. Never squares = squares.append(x) — that stores None and the next round crashes.

✍️ Now write these yourself
  1. 1

    Count how many marks in a list are 33 or above.

    Hint · One counter, one if. The counter goes up by 1, not by the mark.

  2. 2

    Add up only the numbers that divide by 3.

    Hint · A total this time, so it goes up by n — and the test is n % 3 == 0.

  3. 3

    Build a new list holding only the positive numbers.

    Hint · An empty list above the loop, append() inside the if. The new list will be shorter than the old one.

  4. 4

    Find the longest name in a list of names, without max().

    Hint · The champion program with len(name) > len(longest), starting at names[0].

  5. 5

    Count how many numbers are below the average and how many are exactly equal to it.

    Hint · The two-pass shape, with an if…elif…else in the second loop.

Quick Check

Why must largest start at marks[0] rather than at 0?

Quick Check

What is wrong with squares = squares.append(n * n)?

Quick Check

Why does the above-average program need two loops?