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.environ is a dictionary-like mapping of environment variables. Use .get() with a default, because a variable that is not set would raise a KeyError with os.environ["NAME"].
  • os.path joins 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 (0 means success); with a string, as in greet.py, it prints the text to standard error and exits with status 1.
  • sys.version is the interpreter's version as text; sys.version_info is the same as a tuple you can compare.
  • sys.platform names 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 from a to b, both included.
  • choice(seq): one random item of a sequence.
  • shuffle(list): puts a list in random order, in place (it returns None).
  • sample(seq, k): k items 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.