The standard library tour: what is already built in
Python ships with a large collection of modules you can use immediately, with no install and no dependency to maintain. Knowing what is in there is one of the cheapest ways to get faster — a surprising amount of code gets written by people who did not know the answer already existed.
This is a tour rather than a reference. The aim is that you recognise the name later and go and look it up.
Dates and times
from datetime import datetime, date, timedelta
now = datetime.now()
today = date.today()
print(now.strftime("%d %B %Y, %I:%M %p"))
print(today + timedelta(days=30))
27 September 2026, 02:30 PM
2026-10-27
timedelta does date arithmetic properly — it handles month lengths and leap
years so you do not have to.
strftime formats, strptime parses:
parsed = datetime.strptime("25/12/2026", "%d/%m/%Y")
Nobody remembers the codes. Look them up each time; everyone does.
For anything stored or exchanged, use ISO format as the JSON lesson showed:
now.isoformat()
datetime.fromisoformat("2026-09-27T14:30:00")
Time zones are genuinely hard. If you handle them, store UTC and convert only for display.
collections
Better versions of the structures from module 4.
from collections import Counter, defaultdict, deque
print(Counter("mississippi").most_common(2))
[('i', 4), ('s', 4)]
Counter is the counting pattern, built in. most_common is the part you would
otherwise write with sorted and a lambda.
groups = defaultdict(list)
for city, name in pairs:
groups[city].append(name)
defaultdict(list) creates an empty list on first access, replacing the
setdefault and if not in versions from module 4.
queue = deque([1, 2, 3])
queue.appendleft(0)
queue.popleft()
deque adds and removes from both ends quickly. A list's pop(0) has to shift
every remaining item; deque does not. Use it for queues.
pathlib, json, csv
Module 7 covered these. They are standard library — no install needed.
math, statistics, random
import math
print(math.sqrt(16), math.ceil(4.2), math.floor(4.8))
print(math.pi, math.inf)
import statistics
print(statistics.mean(values))
print(statistics.median(values))
statistics.mean handles an empty list by raising a clear error, which beats
sum(x) / len(x) and a ZeroDivisionError.
import random
random.randint(1, 10)
random.choice(["a", "b", "c"])
random.sample(population, 5)
random.shuffle(my_list) # in place, returns None
Never use random for passwords, tokens or anything security-related. It is
predictable by design. Use secrets:
import secrets
token = secrets.token_hex(16)
That distinction has caused real breaches. If it protects something, use
secrets.
itertools
from itertools import combinations, product, groupby, chain
print(list(combinations("abc", 2))) # [('a','b'), ('a','c'), ('b','c')]
print(list(chain([1, 2], [3, 4]))) # [1, 2, 3, 4]
Worth knowing combinations, permutations, product and chain exist. When
you find yourself writing four nested loops to generate every pairing, this is
the module.
os and sys
import os, sys
print(os.environ.get("HOME"))
print(os.environ.get("API_KEY", "not set"))
print(sys.argv) # command-line arguments
print(sys.executable) # which Python is running
sys.exit(1) # quit with a status code
os.environ is how configuration and secrets reach a program in production —
never hard-code an API key.
sys.executable is the diagnostic from module 2, and the one that explains most
ModuleNotFoundError confusion.
For paths, use pathlib rather than os.path. The older API still works and
appears everywhere; pathlib is nicer.
argparse
For anything with command-line arguments, this beats picking through sys.argv:
import argparse
parser = argparse.ArgumentParser(description="Process a CSV file.")
parser.add_argument("input", help="path to the input file")
parser.add_argument("--output", default="out.csv")
parser.add_argument("--verbose", action="store_true")
args = parser.parse_args()
print(args.input, args.output, args.verbose)
You get --help for free, along with validation and clear errors on bad input.
Real tools use it.
logging
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info("Processing started")
logger.warning("Row 42 skipped")
logger.error("Could not connect")
Better than print for anything that runs unattended: levels you can filter,
timestamps, and output you can route to a file without touching the code.
Note __name__ again — it gives each module its own logger, named after it, so
you can tell where a message came from.
Rule of thumb: print while developing, logging for anything that runs on a
server.
re
Regular expressions, for pattern matching beyond what string methods manage:
import re
text = "Contact: priya@example.com or arjun@test.org"
print(re.findall(r"[\w.-]+@[\w.-]+", text))
['priya@example.com', 'arjun@test.org']
The raw string prefix r matters — without it, backslashes get interpreted
twice.
A word of caution: regex is powerful and easy to overuse. "@" in email is
clearer than a pattern when that is all you need, and email validation by regex
is famously a trap. Reach for re when the pattern is genuinely irregular.
Others worth recognising
| Module | For |
|---|---|
time |
sleeping, measuring with perf_counter |
shutil |
copying, moving, deleting folders |
zipfile, tarfile |
archives |
sqlite3 |
a real database, no server needed |
urllib.request |
fetching a URL without installing anything |
unittest |
testing, though we use pytest in module 10 |
dataclasses |
classes with less boilerplate, module 9 |
typing |
type hints beyond the basics |
textwrap |
wrapping and indenting text |
uuid |
unique identifiers |
hashlib |
hashing |
decimal |
exact decimal arithmetic, from module 2 |
enum |
named constant sets |
When to install something instead
The standard library is not always the best tool:
- HTTP requests —
urllib.requestworks;requestsorhttpxis far nicer, and every Python developer knows them. - Data analysis —
pandas, as the CSV lesson noted. - Web applications — Django or FastAPI.
The judgement is whether a dependency earns its place. Every package you add is something to keep updated, and something that can break your build. Prefer the standard library when it is close enough, and reach outside when the gap is real.
How to explore
import statistics
print(dir(statistics))
help(statistics.median)
dir() and help() from module 1, now useful on real modules. The official
documentation at docs.python.org is genuinely well written — the library
reference is worth browsing for twenty minutes, which is enough to recognise
names later.
Practice
- Print today's date in
DD Month YYYYformat, then the date 45 days from now. - Parse
"25/12/2026"into adatetimeand print the weekday. - Count word frequency with
Counterand print the top five. Compare with your module 4 version. - Rewrite a
setdefaultgrouping usingdefaultdict. - Generate a random 32-character hex token with
secrets. Say whyrandomwould be wrong. - Use
combinationsto list every pair from five names. - Read an environment variable with a default, then set it in your shell and run again.
- Write a script taking a filename and an optional
--verboseflag withargparse. Run it with--help. - Replace the prints in one of your programs with
logging, and change the level to see messages disappear. - Extract every four-digit number from a string with
re. - Browse the standard library index at docs.python.org for fifteen minutes and write down three modules you did not know existed.
Next: virtual environments, and why installing a package can break a project you finished last month.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship