Topic 6.4
A Tour of the Standard Library
In one line
Python ships with hundreds of ready-made modules: maths, randomness, dates and time zones, the operating system, iteration tools, statistics and JSON. Knowing what exists, and how to read the documentation, saves you from rewriting what is already built, tested and fast.
Think of it like this
A new flat that comes with a fitted kitchen, a fan, a water heater and a toolbox in the cupboard. You can buy better tools later, but for most jobs the ones already in the cupboard are good enough, and you know where they are. Python calls this idea batteries included: the standard library is the toolbox that arrives with the language.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Standard library
- The collection of modules that comes installed with Python.
- Batteries included
- Python's motto for shipping with a large, useful standard library.
- Pseudo-random
- Looks random but is produced by a formula. The same seed gives the same sequence.
- Seed
- The starting number of a random sequence. Fixing it makes the results repeatable.
- Naive datetime
- A date and time with no time zone attached. Two people can read it as two different moments.
- Aware datetime
- A date and time that knows its time zone.
- UTC
- The world's reference time. Store times in UTC and convert to local time only for display.
- Environment variable
- A named setting that the operating system gives to a program, such as a key or a folder name.
- Documentation (docs)
- The official description of what a module does, with examples.
- Lazy
- Producing values one at a time, only when asked, instead of all at once.
- timedelta
- A length of time, such as 30 days. Adding it to a date gives a new date.
Step by step
01Maths and numbers: math, statistics
math works on single numbers and returns floats (or ints for ceil, gcd, factorial). statistics works on a list and returns summaries.
Use statistics.stdev for a sample (divides by n-1) and pstdev for a whole population.
import math
import statistics
print(math.sqrt(2), math.ceil(2.1), math.gcd(12, 18))
marks = [72, 85, 90, 66, 85]
print(statistics.mean(marks), statistics.median(marks), statistics.mode(marks))02Randomness you can repeat
random.seed(7) fixes the starting point, so the "random" numbers come out the same every run. That is exactly what you want in a test or a machine-learning experiment, because you can rerun it and compare.
randint(a, b) includes both ends. choice picks one item, sample picks several without repeats, shuffle reorders a list in place.
import random
random.seed(7)
print([random.randint(1, 6) for _ in range(5)])
print(random.choice(["red", "green", "blue"]))03Dates, durations and time zones
A small trap first: the module is called datetime, and it also contains a thing called datetime. from datetime import date, datetime, timedelta copies three names out of the module, and the second one is the date-and-time type. Now, date(2026, 10, 9) is a calendar day. Subtracting two dates gives a timedelta; adding a timedelta moves a date. strftime formats it as text (%A weekday name, %d day, %B month name, %Y year).
For zones, build an aware datetime with tzinfo=ZoneInfo("Asia/Kolkata"), then convert with .astimezone(...). The same instant shows a different clock time in each zone. Daylight-saving rules are handled for you by the zone database.
from datetime import date, datetime, timedelta
from zoneinfo import ZoneInfo
launch = date(2026, 10, 9)
print(launch + timedelta(days=30))
meeting = datetime(2026, 10, 9, 9, 30, tzinfo=ZoneInfo("Asia/Kolkata"))
print(meeting.astimezone(ZoneInfo("Europe/London")))04Talking to the system: os and sys
os.environ behaves like a dictionary of environment variables. os.environ.get("NAME", "default") returns a fallback instead of raising KeyError. sys.argv[0] is the script name and the rest are the words typed after it.
Prefer pathlib for paths in new code (Topic 7.6). os.path.join and os.path.splitext still appear in a lot of existing code.
import os
import sys
print(sys.argv) # ['main.py', 'one', 'two'] when run: python main.py one two
print(os.environ.get("NO_SUCH_VAR", "default"))
print(os.path.splitext("report.final.pdf"))05Looping tools: itertools
itertools functions return lazy iterators. Lazy means they hand out one value at a time, only when asked, instead of building the whole list at once (Topic 9.1). So you wrap them in list(...) to see the values. count(10, 5) is infinite, so islice cuts it to the first four. combinations("ABC", 2) gives every pair without repeats; product gives every combination with one pick from each input.
You will meet these again in Topic 9.4 — itertools, with more depth.
import itertools
print(list(itertools.islice(itertools.count(10, 5), 4)))
print(list(itertools.combinations("ABC", 2)))
print(list(itertools.pairwise([1, 4, 9, 16])))06JSON: the format of APIs and AI messages
json.dumps turns Python data into a JSON string (True becomes true, None becomes null); json.loads turns a JSON string back into Python data. Only dicts, lists, strings, numbers, booleans and None convert; a set or a datetime raises TypeError (Topic 7.7 covers the fixes).
Every request to and response from an AI chat API is a dictionary like this, sent as JSON text.
import json
message = {"role": "user", "content": "Hello", "stream": False, "stop": None}
text = json.dumps(message, indent=2)
print(text)
print(json.loads(text) == message)07How to find and read the documentation
When you need to do something, search the docs ("python <task> standard library") before you write it yourself. On the module page, read the introduction, then the section for your function, then look for the example. In a terminal, python -m pydoc statistics prints the same text, and in the REPL help(statistics.median) shows one function.
Check the Python version selector at the top of docs.python.org: the pages are versioned, and a feature marked "Added in version 3.12" does not exist in 3.11.
import statistics
help(statistics.median) # the docstring
print(dir(statistics)[:5]) # names you can reach in the moduleTry it yourself
- 1
Change the seed
In the first example, change
random.seed(7)torandom.seed(8). All the random lines change, but they are again the same on every run. Remove the seed line and they would change on every run, which is why runnable examples here always seed. - 2
Convert another zone
Add
print(meeting.astimezone(ZoneInfo("America/New_York")).isoformat()). Predict the time shown before running. The offset in the output (such as+05:30) tells you how far that zone is from UTC. - 3
Look something up
In the second example, add
print(help(statistics.fmean))or read thestatisticspage on docs.python.org, and find the difference betweenmeanandfmean. Practising this lookup is worth more than any one function.
Code & diagrams
All values are fixed or seeded, so the output is the same every run. Change the seed or the dates and rerun to see how the pieces fit together. `isoformat()` writes a datetime in the standard form `2026-10-09T09:30:00+05:30` (date, `T`, time, then the offset from UTC).
Expected output
sqrt: 1.4142135623730951 | ceil: 3 | gcd: 6
hypot: 5.0 | factorial: 120
rolls: [3, 2, 4, 6, 1]
pick: red
shuffled: [2, 6, 4, 3, 1, 5, 7]
mean: 79.6 | median: 85 | mode: 85
stdev: 10.11
launch: 2026-10-09 Friday, 09 October 2026
30 days later: 2026-11-08
days between: 84
in Kolkata: 2026-10-09T09:30:00+05:30
in London: 2026-10-09T05:00:00+01:00`json.dumps(..., indent=2)` makes readable text; `json.loads` brings it back, and the round trip gives an equal dictionary. `Counter` comes from `collections` (Topic 4.10).
Expected output
python: (3, 13)
argv type: list
missing var: default
path join: data/a.txt | splitext: ('report.final', '.pdf')
cwd empty folder has files: []
[10, 15, 20, 25]
[1, 2, 'a', 'b']
[('A', 'B'), ('A', 'C'), ('B', 'C')]
[(0, 0), (0, 1), (1, 0), (1, 1)]
[(1, 4), (4, 9), (9, 16)]
{
"user": "Asha",
"items": [
{
"sku": "A1",
"qty": 2
}
],
"paid": true,
"note": null
}
True 2
[('i', 4), ('s', 4)]Five made-up log lines, each with a time, a request, a status code and how many milliseconds the reply took. Four small modules (`datetime`, `statistics`, `collections`, `json`) do the whole job in a few lines. `line.split()` cuts a line into words (Topic 3.2).
Expected output
first request at: 09:15:02
average time (ms): 305
median time (ms): 120
status counts: {'200': 3, '500': 1, '404': 1}
{"requests": 5, "slowest_ms": 910, "errors": 2}Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Use a function that does not exist in your version
Call itertools.batched on Python 3.11 (it was added in 3.12), or misspell a name.
import itertools
print(list(itertools.batched("ABCDEFG", 3)))Myth vs fact
Myth
Anything serious needs a third-party package.
Fact
The standard library covers a great deal: files, JSON, CSV, a database (sqlite3), testing, async, dates, regular expressions. Reach for a package when the standard library is clearly not enough.
Myth
random is fine for passwords and tokens.
Fact
random is predictable by design. Use the secrets module for anything security-related.
Myth
A datetime without a time zone is fine as long as I remember which zone I meant.
Fact
You will forget, and so will the next reader. Use aware datetimes (UTC for storage) and convert to local time only for display.
Myth
You must memorise the library.
Fact
Nobody does. Learn the shapes of the main modules and become quick at reading the docs.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Seeded randomness is a reproducibility tool, not just a test trick. In machine learning, the same seed with the same library versions gives the same train/test split and initial weights, which is how you tell whether a change helped. Each library has its own generator and its own seed (Python
random, NumPydefault_rng, PyTorch), and you must seed all of them. - ▸
datetime.now()is a classic source of flaky tests because the answer changes. Production code passes the current time in as a parameter, or reads it through one small function that a test can replace. The same idea applies to randomness and the system environment. - ▸
The standard library moves slowly on purpose. When something is excellent but evolves fast (HTTP clients, data frames, validation), it lives outside as a package (
httpx,pandas,pydantic). The standard library also deprecates and removes old modules over time (some were removed in 3.13), so check the release notes when you upgrade. - ▸
zoneinforeads the IANA database from the operating system. Windows ships no such database, and some minimal containers do not either, soZoneInfo("Asia/Kolkata")can raiseZoneInfoNotFoundErrorthere until you add thetzdatapackage from PyPI as a dependency. Also know the two daylight-saving edge cases: a wall-clock time that never happens (the spring jump) and one that happens twice (the autumn repeat). Thefoldattribute ofdatetimeselects which one you mean, and atimedeltaadded to an aware datetime moves wall-clock time, not elapsed time, so for exact elapsed time convert to UTC first. - ▸
Standard-library speed is real:
itertools,collections,json,reandmathare written in C. A loop in C beats the same loop in Python, so usingsum,sorted,Counteranditertools.chainis often the fastest way to write something, as well as the clearest.
Remember this
- 1
The standard library is a big set of modules installed with Python itself. You never
pip installthem. A module you import without installing anything is almost certainly part of it. Because every Python install has it, code that uses only the standard library runs anywhere Python runs. - 2
mathhas the maths functions (sqrt,ceil,gcd,hypot,factorial,pi), andstatisticshasmean,median,modeandstdevfor lists of numbers.randommakes pseudo-random numbers: withrandom.seed(n)the sequence is the same every time, which is vital for tests and for repeatable AI experiments. (randomis *not* secure: for passwords and tokens usesecrets.) - 3
datetimeholds dates, times and differences between them:date,datetime,timedelta.zoneinfo(Python 3.9) adds time zones using the IANA database (the world's shared list of time zones and their rules):ZoneInfo("Asia/Kolkata")makes a time zone object you can attach to a datetime. The rule that saves most bugs: store and compare times as aware datetimes in UTC, and convert to a local zone only to show a person. A "naive" datetime with no zone is a guess waiting to go wrong. - 4
osandsystalk to the system.sys.argvis the list of command-line words,sys.exit()ends the program,sys.version_infotells the Python version.os.environholds environment variables, andos.pathhas path helpers (Topic 7.6 introduces the modernpathlib).jsonturns Python dicts, lists, strings, numbers, booleans andNoneinto text and back, and is the shape of nearly every web API and AI message. - 5
itertoolsbuilds fast looping pipelines:count,chain,islice,combinations,product,pairwise(3.10),batched(3.12).collections(Topic 4.10) hasCounter,defaultdict,deque. Others you will meet later:pathlib,re,csv,logging,sqlite3,asyncio,dataclasses,functools,argparse,unittest. You do not memorise all of it; you learn where to look. - 6
Reading the documentation is a core skill. At docs.python.org, the *Library Reference* has one page per module, with a summary at the top and every function below it. In the REPL,
help(math.sqrt)shows the docstring anddir(math)lists names. Read the first paragraph, then the examples, then the function you need. A module is also worth checking for an *"added in version"* note, which tells you if it exists in the Python you run.
Explain it without notes
What is the standard library, and how do you know a module belongs to it?
Why do tests and experiments call random.seed(...), and why not use random for passwords?
How should an application treat time zones?
How do you find out how to use a module you have never seen?
Practice
Use statistics to print the mean and median of [4, 8, 15, 16, 23, 42].
Call random.seed(1), then print a list of three dice rolls made with random.randint(1, 6). Then explain in one sentence why running the program again gives the same three numbers.
Print how many days there are from date(2026, 10, 9) to date(2026, 12, 25) (subtract the earlier date from the later one and use .days).
Put the dictionary {"name": "Asha", "scores": [90, 85]} in a variable, then use json.dumps to print it with an indent of 2 and sorted keys.
Trade-offs
- ↔
Standard library vs a third-party package. The standard library has no install step and is stable for years, but sometimes slower or less friendly (
urllibvshttpx,datetimevspendulum). A package may be nicer, but adds a dependency to track, update and trust (Topic 6.9). - ↔
Seeded randomness vs true randomness. Seeding gives repeatability for tests and experiments but must be turned off (or never used) where unpredictability matters, as in security tokens.
Done when you can
Done when you can name at least eight standard-library modules and what each is for.
Done when you can explain
random.seedand whysecretsexists.Done when you can create an aware datetime and convert it between two zones.
Done when you can read a module's page on docs.python.org and use
help()anddir().Done when you can say how to check whether a feature exists in the Python version you run.