LambdaLabTM
Computer Science · Class 11 · Tuples Revisited
TuplesCounting⏱️ 14 min read

Counting & Frequency

Counting one thing is a counter. Counting everything at once — how many 1s, how many 2s, how many of each — is a different problem, and trying to solve it with counters is what makes people inventcount_1, count_2, count_3. The answer is a dictionary, and this is the program it was invented for.

1Program 1 — how many times does one value appear?

📋 The problem

Count how many times 6 was rolled, in a tuple of dice rolls.

count_one.py
# how many sixes?

rolls = (3, 6, 2, 6, 4, 6, 1)
wanted = 6
count = 0

for r in rolls:
    if r == wanted:
        count = count + 1

print(wanted, 'appeared', count, 'times')
Output
6 appeared 3 times
Watch Out
count = count + 1, not count = count + r. A counter goes up by one per match; a total goes up by the item. Mixing them up here would report “6 appeared 18 times”, which is obviously wrong — and only if you look.

The built-in does the same job in one call, and it is what you would write unless the question says not to:

count_builtin.py
rolls = (3, 6, 2, 6, 4, 6, 1)

print(rolls.count(6))
print(rolls.count(5))
Output
3
0

count() answers 0 rather than raising anything for a value that never appears — which is the opposite of index(), and worth remembering because the two look like a pair.

2Program 2 — counting the ones that pass a test

📋 The problem

Count the even and the odd numbers in a tuple.

count_test.py
# two counters, one if…else

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:', evens)
print('Odd: ', odds)
Output
Even: 4
Odd:  3

The check that it worked: 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.

count() cannot do this one. It matches a value, not a rule — there is no way to ask it for “everything even”.

count_passed.py
# the same shape, on a pass mark

marks = (56, 28, 91, 33, 12, 78, 65)
passed = 0
failed = 0

for m in marks:
    if m >= 33:
        passed = passed + 1
    else:
        failed = failed + 1

print('Passed:', passed)
print('Failed:', failed)
Output
Passed: 5
Failed: 2

3Program 3 — the frequency of every value

📋 The problem

For a tuple of dice rolls, report how many times each face came up.

A counter holds one number. Here the answer is six numbers — one per face — and they are not known in advance: on a tuple of names or colours you would not know how many counters to make. What is needed is a box that can grow a new compartment whenever an unseen value turns up, with the value itself as the label. That is a dictionary.

frequency.py
# tally every value into a dictionary

rolls = (3, 6, 2, 6, 4, 6, 1, 2)
freq = {}

for r in rolls:
    if r in freq:
        freq[r] = freq[r] + 1
    else:
        freq[r] = 1

print(freq)
Output
{3: 1, 6: 3, 2: 2, 4: 1, 1: 1}
freq = {}

An empty dictionary — the collector, made before the loop. {} is empty; () would be an empty tuple and [] an empty list.

if r in freq:

Has this face been seen before? On a dictionary, `in` asks about the KEYS, so this is 'is there already a compartment labelled 3?'

freq[r] = freq[r] + 1

Seen before: read the count out, add one, put it back. The same shape as count = count + 1, with the counter picked by name.

freq[r] = 1

First sighting: make the compartment and put 1 in it. Not 0 — you are looking at one right now.

Key Takeaway
The keys arrive in the order they were first seen. The output starts with 3 because 3 was rolled first, not because 3 is the smallest. A dictionary keeps insertion order; it does not sort. Printing it in order of face is a job for sorted(), which the next chapter uses.

4The same thing with get()

get() asks for a key and takes a fallback for when the key is missing. That collapses the whole if…else into one line:

frequency_get.py
# the same tally, in one line inside the loop

rolls = (3, 6, 2, 6, 4, 6, 1, 2)
freq = {}

for r in rolls:
    freq[r] = freq.get(r, 0) + 1

print(freq)
Output
{3: 1, 6: 3, 2: 2, 4: 1, 1: 1}

Read freq.get(r, 0) as “the count for r, or 0 if there is not one yet”. On a face never seen it hands back 0 and 0 + 1 makes the first entry; on a face seen before it hands back the running count. Same answer, four lines shorter, and it is the version experienced Python programmers write.

It works on anything a tuple can hold, not just numbers:

frequency_words.py
# the keys can be strings just as easily

words = ('red', 'blue', 'red', 'green', 'blue', 'red')
freq = {}

for w in words:
    freq[w] = freq.get(w, 0) + 1

print(freq)
Output
{'red': 3, 'blue': 2, 'green': 1}
frequency_words.py

5Program 4 — which value appears most often?

The champion program again, with count() doing the measuring:

most_common.py
# the value that turns up most often

rolls = (3, 6, 2, 6, 4, 6, 1, 2)

best = rolls[0]
best_count = rolls.count(rolls[0])

for r in rolls:
    if rolls.count(r) > best_count:
        best = r
        best_count = rolls.count(r)

print('Most common:', best, '-', best_count, 'times')
Output
Most common: 6 - 3 times
Tip
This one is neat and quietly wasteful. rolls.count(r) walks the whole tuple, and it is called once per item — so an eight-item tuple is walked eight times over. Building the freq dictionary first and finding the champion in it walks the data twice in total. On eight rolls nobody notices; the habit is worth having anyway.

The statistics module has a name for this value — the mode — and computes it in one call. That is the last chapter of this course.

6Recap

A counter goes up by 1

count = count + 1. A total goes up by the item. They look alike and answer different questions.

count() matches a value, not a rule

rolls.count(6) is fine; 'how many even' has to be a loop with an if.

count() answers 0 for a missing value

Unlike index(), which raises ValueError. The pair does not behave as a pair.

Many counters at once means a dictionary

freq = {} above the loop, freq[x] = freq.get(x, 0) + 1 inside it. That one line is the whole idea.

✍️ Now write these yourself
  1. 1

    Count how many marks in a tuple are 75 or above.

    Hint · One counter, one if. Up by 1, not by the mark.

  2. 2

    Count how many names in a tuple start with the letter S.

    Hint · if n[0] == 'S': — or n.startswith('S'), which reads better.

  3. 3

    Tally the grades in a tuple like ('A', 'B', 'A', 'C').

    Hint · The get() line, unchanged. The keys happen to be letters; nothing else is different.

  4. 4

    From the frequency dictionary, print only the values that appeared more than once.

    Hint · Build freq first, then walk it — which is exactly what the next chapter is about.

Quick Check

Why is a dictionary the right tool for counting every value at once?

Quick Check

What does freq.get(r, 0) hand back for a value never seen before?

Quick Check

rolls = (3, 6, 2, 6, 4, 6, 1, 2). Why does the tally print starting with 3?