LambdaLabTM
Computer Science · Class 11 · Python Modules
Modulesstatistics⏱️ 14 min read

The statistics Module

Three functions, one line each, and they replace programs you have already written the long way — the mean is the total-divided-by-count loop, and the mode is the most-common-value loop from the tuples chapter. What is worth the page is the small print: all three have an answer that surprises people the first time.

1mean() — the average you already know

mean.py
import statistics

marks = (72, 65, 88, 91, 54)

print(statistics.mean(marks))
Output
74
Watch Out
74, not 74.0 — and that catches people. The same marks through the loop version print 74.0, because / always makes a float. mean() gives back the exact value in the simplest type that holds it: 370 ÷ 5 is exactly 74, so it hands you the integer 74. Change one mark so the answer is not exact and it becomes a float again.
mean_types.py
import statistics

print(statistics.mean([2, 4, 6]))     # exactly 4
print(statistics.mean([1, 2]))        # 1.5 -- not exact
print(statistics.mean([2.5, 3.5]))    # floats in, float out
Output
4
1.5
3.0

It works on a tuple and on a list alike — anything the for loop could have walked:

mean_both.py
import statistics

print(statistics.mean((72, 65, 88, 91, 54)))
print(statistics.mean([72, 65, 88, 91, 54]))
Output
74
74

2median() — the middle one

The median is the value in the middle once the data is put in order. You do not have to sort it first — median() does that itself, on a copy:

median_odd.py
import statistics

print(statistics.median([7, 1, 5, 3, 9]))
print(sorted([7, 1, 5, 3, 9]))
Output
5
[1, 3, 5, 7, 9]

Five values, so the third one is the middle — 5. With an even count there is no single middle, so it averages the two either side:

median_even.py
import statistics

print(statistics.median([7, 1, 5, 3]))
print(sorted([7, 1, 5, 3]))
Output
4.0
[1, 3, 5, 7]
Key Takeaway
4.0 is not in the data, and that is correct. Sorted, the two middle values are 3 and 5, and their average is 4. On an even count the median is often a value that never appeared — and it comes back as a float because an average was taken.

3Why have a median at all?

Because one wild value drags the mean somewhere useless, and leaves the median alone:

median_vs_mean.py
# four ordinary salaries and one enormous one

import statistics

pay = [18000, 20000, 22000, 21000, 900000]

print('Mean:  ', statistics.mean(pay))
print('Median:', statistics.median(pay))
Output
Mean:   196200
Median: 21000

A mean of 196,200 describes nobody in this office — four of the five earn about a tenth of it. The median, 21,000, describes the middle person honestly. That is the whole reason both exist, and it is why news reports say “median income” rather than average.

4mode() — the most common value

mode.py
import statistics

print(statistics.mode([3, 6, 2, 6, 4, 6, 1]))
print(statistics.mode(['red', 'blue', 'red', 'green']))
Output
6
red

This is the most-common-value program from the tuples chapter, in one call — and unlike mean() and median(), it works on text as happily as on numbers, because “which turns up most often” needs no arithmetic.

Watch Out
When there is a tie, you get whichever came first. In [4, 4, 6, 6] both appear twice, and mode() answers 4. Reverse the list to [6, 6, 4, 4] and the same call answers 6. So a tied mode is not really an answer about the data — it is an answer about the order you happened to store it in. Be careful with any exam question that hands you a tie.
mode_tie.py
import statistics

print(statistics.mode([4, 4, 6, 6]))
print(statistics.mode([6, 6, 4, 4]))
Output
4
6

And when every value is different, every one of them ties on a count of one — so it hands back the first:

mode_all_different.py
import statistics

print(statistics.mode([1, 2, 3]))
Output
1
Note
This behaviour changed in Python 3.8. Before that, a tie raised StatisticsError rather than returning the first value. Old textbooks and old answer keys still say so, so if a printed answer disagrees with your machine, that is usually why. Everything on this page was run on Python 3.12.

5All three refuse empty data

empty.py
import statistics

print(statistics.mean([]))
Output
Traceback (most recent call last):
  File "empty.py", line 3, in <module>
    print(statistics.mean([]))
          ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/statistics.py", line 486, in mean
    raise StatisticsError('mean requires at least one data point')
statistics.StatisticsError: mean requires at least one data point

Which is right — there is no average of nothing. A program that builds its data from user input has to check len() before it summarises, exactly as it would before max().

6Program — a marks summary

📋 The problem

Print a full summary of a tuple of marks: how many, the three averages, the highest and the lowest.

report.py
# everything you can say about a set of marks, in eight lines

import statistics

marks = (72, 65, 88, 91, 54, 65, 77)

print('Count:  ', len(marks))
print('Mean:   ', round(statistics.mean(marks), 2))
print('Median: ', statistics.median(marks))
print('Mode:   ', statistics.mode(marks))
print('Lowest: ', min(marks))
print('Highest:', max(marks))
Output
Count:   7
Mean:    73.14
Median:  72
Mode:    65
Lowest:  54
Highest: 91

len(), min() and max() are built-ins and need no import; the three averages come from the module. The round(…, 2) is on the mean only, because it is the one that produces a long decimal — 73.14285714285714 without it.

report.py

7The from form, if you prefer it

from_import.py
from statistics import mean, median, mode

marks = (72, 65, 88, 91, 54, 65)

print(mean(marks), median(marks), mode(marks))
Output
72.5 68.5 65

Worth knowing here because statistics. is eleven characters and the calls are short. import statistics as st is the middle road — st.mean(marks) still says where mean came from.

8Recap

mean() may hand back an int

370 ÷ 5 is exactly 74, so you get 74, not 74.0. The loop version always gives a float, because / always does.

median() sorts for you

And on an even count it averages the two middle values — so the answer can be a number that is not in the data.

The median survives a wild value

One 900000 salary drags the mean to 196200 and leaves the median at 21000. That is why both exist.

A tied mode returns whichever came first

[4, 4, 6, 6] gives 4 and [6, 6, 4, 4] gives 6. Python 3.8 changed this; before it, a tie was an error.

All three refuse empty data

StatisticsError, not 0. Check len() before summarising anything a user supplied.

✍️ Now write these yourself
  1. 1

    Read five marks into a tuple and print the mean, median and mode.

    Hint · Build the tuple with a loop — marks = marks + (int(input()),) — then three calls.

  2. 2

    Compare statistics.mean() with your own total / len() loop on the same data, and print both.

    Hint · They agree in value and may differ in type — 74 against 74.0. That is the whole exercise.

  3. 3

    Add one enormous value to a list of ordinary ones and print the mean and median before and after.

    Hint · The mean moves a long way; the median barely moves at all. Say in one line which you would report.

  4. 4

    Count how many marks are above the mean, and how many below.

    Hint · Work the mean out first, then walk the tuple — the two-pass shape from the tuples chapter.

  5. 5

    Print the mode of a tuple of grades, and check what happens when two grades tie.

    Hint · Whichever appeared first wins. Reorder the tuple and run it again to prove it to yourself.

Quick Check

statistics.mean((72, 65, 88, 91, 54)) prints 74, not 74.0. Why?

Quick Check

What is statistics.median([7, 1, 5, 3])?

Quick Check

What does statistics.mode([4, 4, 6, 6]) give on Python 3.12?