A dataset is just a list of numbers, but a raw list does not tell you what you need to know. Is it centred around ten or a thousand? Are the values tightly clustered or spread across a wide range? Before you ever fit a model, you need a compact summary that answers those questions. The three most important summaries are the mean (the centre), the variance (the spread), and the standard deviation (the spread in the same units as the data). In this lesson you build all three from scratch, and you learn the classic trap that hides inside the variance formula.
The mean: the balance point
The mean is the arithmetic average: add every value and divide by how many there are. It is the 'centre of mass' of the data — if you placed equal weights at every data point on a see-saw, the mean is where the fulcrum would balance.
Because every point contributes equally, the mean is pulled toward outliers. A single extreme value can shift it noticeably, which is why the mean alone is never enough. Still, it is the right starting point, and every other summary in this lesson is defined relative to it. Computing it by hand before you call sum(data) / len(data) is how you know what that one-liner is really doing.
data = [12, 15, 9, 18, 11]
mean = sum(data) / len(data)
print("mean =", round(mean, 2))
Variance: how far do the points wander?
Variance measures spread by asking: on average, how far is each point from the mean? The distance is x - mean, but distances above and below would cancel out, so we square them first. The result is the mean squared deviation.
For a population — every member of the group — divide by n. For a sample — a subset you use to estimate the whole — divide by n - 1. The smaller denominator makes the sample variance slightly larger, compensating for the fact that a sample usually misses the extremes. Using n when you should use n - 1 is the most common mistake in introductory statistics, and it leads to models that look more confident than they really are.
flowchart TD D["Dataset"] --> M["Mean"] M --> V["Variance:<br/>average squared<br/>distance from mean"] V --> S["Standard Deviation:<br/>square root of variance"] style M fill:#166534,color:#fff style V fill:#b45309,color:#fff style S fill:#1d4ed8,color:#fff
data = [2, 4, 4, 4, 5, 5, 7, 9]
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
print("population variance =", round(variance, 2))
Standard deviation: variance in the original units
Variance is measured in squared units — squared dollars, squared years — which is hard to interpret. The standard deviation is simply the square root of the variance, and that puts the spread back into the same units as the data itself.
If a dataset of ages has mean 30 and standard deviation 5, most values sit within a few years of 30. The standard deviation is the number you will see reported in research papers, in medical trials, and in every machine-learning baseline. It is the bridge between the abstract math and the real world. When you later read that a model's error has standard deviation 2.3, you will know exactly what that means.
import math
data = [2, 4, 4, 4, 5, 5, 7, 9]
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
std_dev = math.sqrt(variance)
print("std dev =", round(std_dev, 2))
Reading the numbers together
A low mean with a high standard deviation tells you the data is centred low but scattered widely. A high mean with a low standard deviation tells you most values sit tightly around a large number. These two numbers — centre and spread — are the first thing a data scientist looks at, and they are the foundation of every decision that follows: whether to scale, whether to remove outliers, and which model is appropriate. Without them, you are guessing in the dark.
flowchart LR P["Population<br/>divide by n"] --> R["Sample<br/>divide by n-1"] R --> W["Why? Sample<br/>underestimates<br/>true spread"] style P fill:#166534,color:#fff style R fill:#b45309,color:#fff
What does this print? The mean of a three-number list.
data = [10, 20, 30] print(sum(data) / len(data))
Sum is 60. There are 3 items.
60 divided by 3 is 20.0.
Write mean(data) that returns the arithmetic mean of a non-empty list of numbers.
def mean(data):
pass
Add the numbers with sum(data).
Divide by how many there are with len(data).
def mean(data):
return sum(data) / len(data)
Write population_variance(data) that returns the population variance: the average of the squared distances from the mean. Use n = len(data) as the denominator.
def population_variance(data):
pass
Compute the mean first.
Sum (x - mean) ** 2 for every x, then divide by n.
def population_variance(data):
n = len(data)
mean = sum(data) / n
return sum((x - mean) ** 2 for x in data) / n
This function is meant to compute the sample standard deviation (dividing by n - 1), but it divides by n instead. Fix the denominator.
import math
def sample_std_dev(data):
n = len(data)
mean = sum(data) / n
variance = sum((x - mean) ** 2 for x in data) / n
return math.sqrt(variance)
The sample variance divides by n - 1, not n.
Change the denominator in the variance line.
import math
def sample_std_dev(data):
n = len(data)
mean = sum(data) / n
variance = sum((x - mean) ** 2 for x in data) / (n - 1)
return math.sqrt(variance)
Write summarise(data) that returns a dict {'mean': m, 'variance': v, 'std_dev': s} for the population of data. Use math.sqrt for the standard deviation. data is a non-empty list of numbers.
import math
def summarise(data):
pass
Compute mean, then variance, then math.sqrt(variance).
Return a dict with the three keys.
import math
def summarise(data):
n = len(data)
mean = sum(data) / n
variance = sum((x - mean) ** 2 for x in data) / n
std_dev = math.sqrt(variance)
return {'mean': mean, 'variance': variance, 'std_dev': std_dev}
Recap
- The mean is the arithmetic average: the centre of mass of the data.
- Variance is the average squared distance from the mean; it quantifies spread in squared units.
- Standard deviation is the square root of variance, bringing spread back to the original units.
- For a population, divide variance by
n; for a sample, divide byn - 1to correct the underestimate. - Always check whether your data is the whole group or a subset before you choose the denominator. Getting this wrong makes every downstream number — confidence intervals, test statistics, model scores — slightly but systematically dishonest.