The statistics Module

Reviewed & published by Brayan K

The statistics module is Python's built-in toolkit for calculating averages, spread, and quantiles directly on ordinary lists of numbers, with zero external dependencies.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Before you reach for numpy or pandas, this lightweight standard-library module handles the everyday math — means, medians, modes, and standard deviation — in a few clear function calls.

What You'll Learn in This Lesson

1 Measures of Center: mean, median, mode

The three classic "averages" answer different questions. The mean is the arithmetic average, the median is the middle value when sorted, and the mode is the most common value. Each is a single function call:

import statistics as st

data = [12, 15, 15, 18, 22, 30]

print("mean:", st.mean(data))       # mean: 18.666666666666668
print("median:", st.median(data))   # median: 16.5
print("mode:", st.mode(data))       # mode: 15

💡 Why the median matters:

The median ignores extreme outliers. If one billionaire walks into a room, the mean income skyrockets but the median barely moves. For skewed data like incomes or house prices, the median is usually the more honest "typical" value.

import statistics as st

scores = [70, 85, 85, 90, 95, 100]

print("mean:", round(st.mean(scores), 2))
print("median:", st.median(scores))
print("mode:", st.mode(scores))
print("multimode:", st.multimode([1, 1, 2, 2, 3]))

# ✅ Expected output:
# mean: 87.5
# median: 87.5
# mode: 85
# multimode: [1, 2]

2 Measures of Spread: variance & standard deviation

Center tells you where the data sits; spread tells you how scattered it is. Variance is the average squared distance from the mean, and standard deviation is its square root (back in the original units). Python gives you both a sample and a population version:

import statistics as st

data = [12, 15, 15, 18, 22, 30]

# Sample (divides by n-1) — use for a sample of a bigger group
print("variance:", round(st.variance(data), 4))   # variance: 42.2667
print("stdev:", round(st.stdev(data), 4))         # stdev: 6.5013

# Population (divides by n) — use when data IS everything
print("pvariance:", round(st.pvariance(data), 4)) # pvariance: 35.2222
print("pstdev:", round(st.pstdev(data), 4))       # pstdev: 5.9348
import statistics as st

# Two classes with the same mean but different consistency
steady = [80, 81, 79, 80, 80]
swingy = [60, 100, 70, 90, 80]

print("steady mean:", st.mean(steady))
print("swingy mean:", st.mean(swingy))
print("steady stdev:", round(st.stdev(steady), 2))
print("swingy stdev:", round(st.stdev(swingy), 2))

# ✅ Expected output:
# steady mean: 80
# swingy mean: 80
# steady stdev: 0.71
# swingy stdev: 15.81

3 Quantiles & Specialized Means

Quantiles cut sorted data into equal-sized buckets. Pass n=4 to get the three quartile cut-points (25%, 50%, 75%), or n=100 for percentiles. Python also offers faster and specialized averages:

import statistics as st

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Quartile cut-points (the values at 25%, 50%, 75%)
print("quartiles:", st.quantiles(data, n=4))
# quartiles: [2.75, 5.5, 8.25]

# fmean: a faster, always-float arithmetic mean (Python 3.8+)
print("fmean:", st.fmean([2, 4, 6, 8]))     # fmean: 5.0

# geometric_mean: for growth rates / ratios
print("geometric:", st.geometric_mean([2, 4, 8]))  # geometric: 4.0

# harmonic_mean: for rates / speeds
print("harmonic:", st.harmonic_mean([40, 60]))     # harmonic: 48.0

Use fmean when you just want a fast average of floats, geometric_mean for things that multiply (like yearly growth), and harmonic_mean when averaging rates (like average speed over equal distances).

import statistics as st

# Average speed for two equal-distance legs of a trip
# (60 km/h out, 40 km/h back) — harmonic mean is correct here
print("avg speed:", st.harmonic_mean([60, 40]))

# Compound growth: 2x then 8x averages to 4x per step
print("growth:", st.geometric_mean([2, 8]))

# Percentile cut-points
data = list(range(1, 21))
print("deciles:", st.quantiles(data, n=10)[:3])

# ✅ Expected output:
# avg speed: 48.0
# growth: 4.0
# deciles: [2.1, 4.2, 6.3]

🎯 YOUR TURN: Fill in the Blanks

Replace each ___ with the correct statistics function so the output matches. Think about which "average" each comment describes.

import statistics as st

prices = [9.99, 14.99, 14.99, 19.99, 49.99]

# 1. The arithmetic average -> use ___
avg = st.___(prices)
print("avg:", round(avg, 2))

# 2. The middle value -> use ___
mid = st.___(prices)
print("middle:", mid)

# 3. The most common value -> use ___
common = st.___(prices)
print("common:", common)

# Expected output:
# avg: 21.99
# middle: 14.99
# common: 14.99

Common Errors

❌ Calling a statistic on an empty list

st.mean([])   # StatisticsError: mean requires at least one data point

✅ Guard for emptiness first

data = []
avg = st.mean(data) if data else 0
print(avg)    # 0

❌ Expecting mode to handle ties

st.mode([1, 1, 2, 2])   # returns just 1, silently ignoring the tie

✅ Use multimode when ties are possible

print(st.multimode([1, 1, 2, 2]))   # [1, 2]

❌ Mixing up sample and population spread

# Using pstdev on a SAMPLE under-reports the real spread

✅ Use stdev for samples, pstdev only for full populations

sample = [2, 4, 4, 4, 5, 5, 7, 9]
print(round(st.stdev(sample), 4))    # 2.1381  (sample)
print(round(st.pstdev(sample), 4))   # 2.0     (population)

🎯 Mini Challenge: Grade Report

Build a small grade summary that reports the class average, the median, how spread out the scores are, and the top-quartile cutoff.

import statistics as st

grades = [55, 62, 70, 71, 78, 85, 88, 90, 94, 100]

print("Average:", round(st.mean(grades), 1))
print("Median :", st.median(grades))
print("Spread :", round(st.stdev(grades), 1))

# The 75% cut-point is the 3rd of 4 quantiles
top_quartile = st.quantiles(grades, n=4)[2]
print("Top 25% starts at:", top_quartile)

# ✅ Expected output:
# Average: 79.3
# Median : 81.5
# Spread : 14.6
# Top 25% starts at: 91.0

📚 Keep Learning

Frequently Asked Questions

Lesson complete — you can summarize data with pure Python!

You can now find the mean, median, and mode, measure spread with sample (stdev) and population (pstdev) standard deviation, split data with quantiles, and choose specialized means like fmean and geometric_mean — all without any external libraries.

Practice quiz

What does statistics.mean compute?

  • The middle value when sorted
  • The most common value
  • The arithmetic average
  • The largest value

Answer: The arithmetic average. mean is the arithmetic average — the sum of values divided by how many there are.

What is statistics.median([12, 15, 15, 18, 22, 30])?

  • 15
  • 16.5
  • 18
  • 18.67

Answer: 16.5. With an even count, the median is the average of the two middle values: (15 + 18) / 2 = 16.5.

What does statistics.mode return when several values tie for most common?

  • A list of all the most-common values
  • The single first most-common value it encounters
  • It always raises an error on ties
  • The average of the tied values

Answer: The single first most-common value it encounters. mode returns only the first most-common value; use multimode to get a list of all of them.

What does statistics.multimode([1, 1, 2, 2, 3]) return?

  • [1]
  • [2]
  • [1, 2]
  • 1

Answer: [1, 2]. multimode returns a list of all values sharing the top frequency — here both 1 and 2 appear twice.

What is the difference between stdev and pstdev?

  • stdev divides by n-1 (sample); pstdev divides by n (population)
  • stdev is for integers, pstdev for floats
  • They are identical
  • pstdev divides by n-1; stdev divides by n

Answer: stdev divides by n-1 (sample); pstdev divides by n (population). stdev/variance are the sample versions (divide by n-1); pstdev/pvariance are population versions (divide by n).

Which should you use when your data is a SAMPLE of a larger population?

  • pstdev
  • pvariance
  • stdev
  • harmonic_mean

Answer: stdev. Use the sample versions (stdev, variance) unless your list truly contains the entire population.

What does statistics.quantiles(data, n=4) return?

  • Four equal buckets of the data
  • The three quartile cut-points (at 25%, 50%, 75%)
  • The single median value
  • The four largest values

Answer: The three quartile cut-points (at 25%, 50%, 75%). n=4 returns the three cut-points that divide sorted data into four equal-sized groups.

Which mean is correct for averaging rates like speeds over equal distances?

  • mean
  • geometric_mean
  • harmonic_mean
  • fmean

Answer: harmonic_mean. harmonic_mean is the right average for rates; harmonic_mean([60, 40]) gives 48.0.

What does statistics.mean([]) do on an empty list?

  • Returns 0
  • Returns None
  • Raises StatisticsError
  • Returns an empty list

Answer: Raises StatisticsError. mean raises StatisticsError on empty input — it requires at least one data point.

When should you prefer statistics over numpy or pandas?

  • For huge arrays needing vectorized speed
  • For small datasets with zero dependencies
  • Only when working with DataFrames
  • Never — they are always slower

Answer: For small datasets with zero dependencies. statistics is ideal for small datasets and zero-dependency scripts; numpy/pandas win on large, vectorized data.

Continue this course

Frequently asked questions

What is the statistics module in Python?

It's a built-in standard-library module that gives you common statistical calculations — mean, median, mode, standard deviation, variance, quantiles and more — without installing anything. It works on plain Python lists of numbers and is perfect for small to medium datasets where pulling in numpy or pandas would be overkill.

What's the difference between stdev and pstdev?

stdev (and variance) compute the SAMPLE standard deviation, which divides by n-1 and is what you want when your data is a sample drawn from a larger population. pstdev (and pvariance) compute the POPULATION value, dividing by n, and are correct when your data IS the entire population. The sample versions give a slightly larger number to correct for the bias of estimating from a sample.

When should I use statistics instead of numpy or pandas?

Reach for statistics when you have a small dataset, want zero dependencies, or are writing a script that should run anywhere with just Python installed. Switch to numpy or pandas when you have large arrays (thousands+ of values), need vectorized speed, or already work with DataFrames — those libraries are dramatically faster on big data but add install weight.

What does mode do when there are several most-common values?

statistics.mode returns the single first most-common value it encounters. If you expect ties — several values sharing the top frequency — use statistics.multimode instead, which returns a list of all the most-common values. This avoids surprises when your data genuinely has more than one peak.