Useful Standard Library
A tour of modules that ship with Python: os, sys, datetime, random, collections and json.
Batteries included
The standard library is the collection of modules included with every standard Python installation. It covers files, dates, text, math, random numbers, data formats, networking, testing and much more. Because it ships with every installation, code that uses only the standard library runs anywhere Python runs, with nothing extra to install. That is what Python's motto "batteries included" means.
You use a standard module the same way as any other: with
import. How importing works is explained in
Modules, Packages, pip and Virtual Environments.
Finding your way
The official documentation at docs.python.org has a page for every module, under "Library Reference". In the REPL you can also ask Python directly:
import math
help(math) # the full manual page of a module (press q to leave)
help(math.sqrt) # the documentation of one function
print(dir(math)) # every name the module defines
help() shows the docstrings written in the module's
source code; the page on code style
explains how to write your own.
os: the operating system
The os module talks to the operating system: the
current folder, the files in a folder, environment variables and
processes. Some of the most used functions:
import os
os.makedirs("reports", exist_ok=True)
for name in ["2026-02.csv", "2026-01.csv", "notes.txt"]:
with open(os.path.join("reports", name), "w") as file:
file.write("")
print(sorted(os.listdir("reports")))
print(os.path.exists(os.path.join("reports", "notes.txt")))
print(os.path.splitext("2026-01.csv"))
print(os.environ.get("REPORT_LANGUAGE", "en"))
['2026-01.csv', '2026-02.csv', 'notes.txt']
True
('2026-01', '.csv')
en
-
os.getcwd()returns the current working directory: the folder that relative paths start from. -
os.listdir(folder)lists the names in a folder, in no guaranteed order, so sort them when order matters. -
os.environis a dictionary-like mapping of environment variables. Use.get()with a default, because a variable that is not set would raise aKeyErrorwithos.environ["NAME"]. -
os.pathjoins and splits paths as strings, using the right separator for the operating system.
from pathlib import Path
folder = Path("reports")
folder.mkdir(exist_ok=True)
(folder / "notes.txt").write_text("Order more paper\n")
print(sorted(path.name for path in folder.iterdir()))
print((folder / "notes.txt").suffix)
['notes.txt'] .txt
sys: the interpreter and the command line
The sys module gives access to the running Python
interpreter itself.
Command-line arguments
A
command-line argument
is a value typed after the script name when you start a program,
such as Ada in python3 greet.py Ada.
Python puts them in the list sys.argv, as strings.
sys.argv[0] is the script's name (with the path as you
typed it), so the real arguments start at index 1.
# greet.py
import sys
if len(sys.argv) != 2:
sys.exit("Usage: python3 greet.py NAME")
name = sys.argv[1]
print(f"Hello, {name}!")
python3 greet.py Ada # prints: Hello, Ada!
python3 greet.py # prints: Usage: python3 greet.py NAME
A script run without arguments has only its name in
sys.argv:
import sys
print(sys.argv)
print(len(sys.argv) - 1, "arguments")
['example.py'] 0 arguments
Arguments are always strings: convert with int() or
float() when you need numbers. For programs with
options such as --verbose, the standard module
argparse parses them and writes a help text for you.
Exiting, version and platform
-
sys.exit()stops the program. With a number, it sets the exit status (0means success); with a string, as ingreet.py, it prints the text to standard error and exits with status 1. -
sys.versionis the interpreter's version as text;sys.version_infois the same as a tuple you can compare. -
sys.platformnames the operating system:"linux","darwin"(macOS) or"win32"(Windows, also 64-bit).
import sys
if sys.version_info < (3, 8):
sys.exit("This program needs Python 3.8 or later")
print("Python version is recent enough")
print(sys.version_info.major)
Python version is recent enough 3
datetime: dates and times
The datetime module represents
calendar dates, times of day and durations as objects you can
compare, add and format. Its main classes are date (a
day), datetime (a day plus a time) and
timedelta (a length of time).
date and timedelta
from datetime import date, timedelta
launch = date(2026, 4, 1)
print(launch)
print(launch.year, launch.month, launch.day)
deadline = launch + timedelta(days=30)
print(deadline)
days_left = date(2026, 12, 25) - launch
print(days_left.days)
print(deadline > launch)
2026-04-01 2026 4 1 2026-05-01 268 True
Subtracting two dates gives a timedelta; adding a
timedelta to a date gives a new date. Month lengths and
leap years are handled for you.
datetime, strftime and strptime
strftime() ("string format time") turns a date or
datetime into text, following format codes such as
%Y (year), %m (month),
%d (day), %H (hour, 24-hour clock) and
%M (minute). strptime() ("string parse
time") does the opposite: it reads text in a given format and
returns a datetime.
from datetime import datetime
meeting = datetime(2026, 9, 30, 14, 30)
print(meeting)
print(meeting.strftime("%d/%m/%Y %H:%M"))
print(meeting.strftime("%A %d %B %Y"))
arrival = datetime.strptime("30-09-2026 09:15", "%d-%m-%Y %H:%M")
print(arrival)
print(meeting - arrival)
2026-09-30 14:30:00 30/09/2026 14:30 Wednesday 30 September 2026 2026-09-30 09:15:00 5:15:00
ISO 8601 format
For storing and exchanging dates, use the international standard
ISO 8601: year first, such as
2026-09-30T14:30:00. It is unambiguous in every
country, and text in this format sorts in date order.
from datetime import date, datetime
meeting = datetime(2026, 9, 30, 14, 30)
text = meeting.isoformat()
print(text)
print(datetime.fromisoformat(text) == meeting)
print(date.fromisoformat("2026-12-25").strftime("%B %d"))
2026-09-30T14:30:00 True December 25
random: pseudo-random numbers
The random module picks numbers and items by chance —
for games, simulations and test data.
-
random(): a float from 0.0 up to, but not including, 1.0. -
randint(a, b): an integer fromatob, both included. choice(seq): one random item of a sequence.-
shuffle(list): puts a list in random order, in place (it returnsNone). -
sample(seq, k):kitems from different positions, without repeats, as a new list.
Seeding for repeatable results
The numbers are not truly random. They are
pseudo-random: calculated by an algorithm from a starting
value. A random seed is that
starting value. Without a seed, Python picks one from the operating
system, so every run differs. With random.seed(n), the
same seed always produces the same sequence on the same Python
version — which is how the output below can be shown exactly.
import random
random.seed(42)
print(random.random())
print(random.randint(1, 6))
print(random.choice(["rock", "paper", "scissors"]))
cards = ["A", "K", "Q", "J", "10"]
random.shuffle(cards)
print(cards)
print(random.sample(range(1, 50), 6))
0.6394267984578837 1 scissors ['J', '10', 'A', 'K', 'Q'] [48, 7, 44, 35, 6, 38]
import random
random.seed(7)
first = [random.randint(1, 6) for _ in range(5)]
random.seed(7)
second = [random.randint(1, 6) for _ in range(5)]
print(first)
print(first == second)
[3, 2, 4, 6, 1] True
collections: specialized containers
The collections module adds container types that solve
common tasks with less code than a plain
dictionary or
list.
Counter
A Counter is a dictionary that counts
how often each item occurs. Give it any iterable; missing items
count as 0 instead of raising a KeyError.
most_common(n) returns the n most frequent
items with their counts.
from collections import Counter
levels = ["INFO", "WARNING", "INFO", "ERROR", "INFO", "WARNING"]
counts = Counter(levels)
print(counts)
print(counts["INFO"])
print(counts["CRITICAL"])
print(counts.most_common(1))
counts.update(["ERROR", "ERROR"])
print(counts.most_common(2))
Counter({'INFO': 3, 'WARNING': 2, 'ERROR': 1})
3
0
[('INFO', 3)]
[('INFO', 3), ('ERROR', 3)]
Items with the same count keep the order in which they were first
seen, which is why 'INFO' comes before
'ERROR' in the last line.
defaultdict
A defaultdict is a dictionary
that creates a default value the first time a missing key is used.
You pass it a function that makes that value, such as
list (an empty list) or int (zero). It is
ideal for grouping:
from collections import defaultdict
orders = [("Ada", "keyboard"), ("Grace", "mouse"), ("Ada", "monitor")]
by_customer = defaultdict(list)
for customer, item in orders:
by_customer[customer].append(item)
print(dict(by_customer))
print(by_customer["Linus"])
print(len(by_customer))
{'Ada': ['keyboard', 'monitor'], 'Grace': ['mouse']}
[]
3
Note the last line: merely reading a missing key, as
by_customer["Linus"] does, adds it. Use
in or .get() when you only want to look.
namedtuple
A namedtuple is a tuple whose
items also have names. It is as light and immutable as a tuple, but
point.x reads better than point[0].
from collections import namedtuple
Reading = namedtuple("Reading", ["sensor", "celsius"])
kitchen = Reading("Kitchen", 21.5)
print(kitchen)
print(kitchen.celsius)
print(kitchen[0])
sensor, celsius = kitchen
print(sensor, celsius)
Reading(sensor='Kitchen', celsius=21.5) 21.5 Kitchen Kitchen 21.5
When the record needs methods or must be changeable, use a dataclass instead.
deque
A deque ("deck", double-ended queue) adds and removes
items quickly at both ends, where a list is only fast at
the end. With maxlen, it keeps only the newest items.
from collections import deque
recent = deque(maxlen=3)
for page in ["home", "about", "blog", "contact"]:
recent.append(page)
print(recent)
print(recent.popleft())
print(list(recent))
deque(['about', 'blog', 'contact'], maxlen=3) about ['blog', 'contact']
json: data as text
JSON is the most common text format for exchanging data between
programs and web services. The json module converts
between Python values and JSON text: dumps() ("dump
string") turns a value into a string, loads() ("load
string") turns a string back into a value.
import json
order = {"id": 1042, "customer": "Ada", "items": ["keyboard", "mouse"],
"paid": True, "note": None}
text = json.dumps(order)
print(text)
print(type(text).__name__)
back = json.loads(text)
print(back == order)
print(back["items"][0])
{"id": 1042, "customer": "Ada", "items": ["keyboard", "mouse"], "paid": true, "note": null}
str
True
keyboard
Python's True, False and
None become JSON's true,
false and null. Pass
indent=2 to dumps() for readable,
multi-line output. The round trip is not always exact: JSON has no
tuples and only string keys.
import json
data = {1: (20.5, 21.0)}
print(json.loads(json.dumps(data)))
{'1': [20.5, 21.0]}
To read and write JSON files, use
json.load() and json.dump() with a file
object; see files and paths.
math: beyond the operators
The math module holds mathematical functions and
constants for floats and integers.
import math
print(math.pi)
print(math.sqrt(2))
print(math.ceil(4.2), math.floor(4.8))
print(math.factorial(5), math.gcd(12, 18))
print(math.hypot(3, 4))
print(0.1 + 0.2 == 0.3, math.isclose(0.1 + 0.2, 0.3))
3.141592653589793 1.4142135623730951 5 4 120 6 5.0 False True
math.isclose() is the right way to compare floats,
because of the small rounding errors explained in
Operators and Expressions. For money, where those errors are not acceptable, the standard
module decimal calculates in base 10, so amounts such
as 0.10 are stored exactly.