Free lab Real Python 3. Zero installs. Your code stays in this browser. Open the playground
227 entries · 15 categories · every example executed

Python reference

Every keyword, operator, built-in function and common method in one place. Each entry gives the syntax, a one-line explanation and an example whose output was produced by actually running it. Search it, link to any entry, or print the one-page version for your desk.

227 entries

Keywords & syntax

The statements every Python program is built from. Learn it in a course

if / elif / else

if cond:
    ...
elif other:
    ...
else:
    ...

Run the first block whose condition is true.

Try it
score = 72
if score >= 90:
    print("A")
elif score >= 70:
    print("C")
else:
    print("F")
C

for … in

for item in iterable:
    ...

Repeat a block once for each item in any iterable.

Try it
for fruit in ["apple", "pear"]:
    print(fruit)
apple
pear

while

while cond:
    ...

Repeat a block for as long as a condition stays true.

Try it
n = 3
while n > 0:
    print(n)
    n -= 1
3
2
1

break / continue

break
continue

break leaves the loop now; continue skips to the next pass.

Try it
for n in range(10):
    if n % 2:
        continue
    if n > 6:
        break
    print(n)
0
2
4
6

for … else

for x in items:
    ...
else:
    ...

The else block runs only if the loop finished without break.

Try it
for n in [3, 5, 7]:
    if n % 2 == 0:
        print("found even")
        break
else:
    print("no even numbers")
no even numbers

def / return

def name(params):
    return value

Define a reusable function; return sends a value back.

Try it
def area(w, h):
    return w * h

print(area(3, 4))
12

lambda

lambda params: expression

A small anonymous function made of a single expression.

Try it
square = lambda x: x * x
print(square(7))
49

class

class Name(Base):
    ...

Define a new type of object.

Try it
class Dog:
    def __init__(self, name):
        self.name = name

print(Dog("Rex").name)
Rex

try / except / else / finally

try:
    ...
except Error as e:
    ...
else:
    ...
finally:
    ...

Handle errors; else runs if nothing failed, finally always runs.

Try it
try:
    n = int("42")
except ValueError:
    print("not a number")
else:
    print("parsed", n)
finally:
    print("done")
parsed 42
done

raise

raise Error(message)

Signal an error yourself.

Try it
try:
    raise ValueError("age must be positive")
except ValueError as e:
    print(e)
age must be positive

with

with expr as name:
    ...

Use a context manager that always cleans up, even on error.

Try it
with open("note.txt", "w") as f:
    f.write("hi")
print(f.closed)
True

import / from … import … as

import module
from module import name as alias

Load a module, or specific names from it.

Try it
import math
from statistics import mean as avg
print(math.pi > 3, avg([1, 2, 3]))
True 2

pass

pass

A statement that does nothing; a placeholder for an empty block.

Try it
def todo():
    pass

print(todo())
None

del

del name
del container[key]

Remove a name, a list item or a dictionary key.

Try it
nums = [1, 2, 3]
del nums[0]
print(nums)
[2, 3]

assert

assert cond, message

Stop with AssertionError if a condition you rely on is false.

Try it
try:
    assert 2 + 2 == 5, "maths is broken"
except AssertionError as e:
    print(e)
maths is broken

global / nonlocal

global name
nonlocal name

Assign to a variable from an outer scope instead of creating a local one.

Try it
count = 0
def bump():
    global count
    count += 1
bump(); bump()
print(count)
2

yield

def gen():
    yield value

Turn a function into a generator that produces values lazily.

Try it
def countdown(n):
    while n:
        yield n
        n -= 1

print(list(countdown(3)))
[3, 2, 1]

match / case

match value:
    case pattern:
        ...

Structural pattern matching (Python 3.10+).

Try it
def describe(cmd):
    match cmd.split():
        case ["go", direction]:
            return f"moving {direction}"
        case ["quit"]:
            return "bye"
        case _:
            return "unknown"

print(describe("go north"))
print(describe("dance"))
moving north
unknown

Conditional expression

a if cond else b

Choose between two values in a single expression.

Try it
age = 20
print("adult" if age >= 18 else "minor")
adult

Walrus :=

(name := expression)

Assign and use a value in the same expression.

Try it
words = ["hi", "hello", "hey"]
if (n := len(words)) > 2:
    print(f"{n} words")
3 words

Comments & docstrings

# comment
"""Docstring."""

# starts a comment; a string as a function's first line documents it.

Try it
def greet():
    """Say hello."""
    return "hello"  # the result

print(greet.__doc__)
Say hello.

Operators

Arithmetic, comparison, logic, unpacking and slicing. Learn it in a course

Arithmetic

+  -  *  /  //  %  **

/ always gives a float; // floors; % is the remainder; ** is power.

Try it
print(7 / 2, 7 // 2, 7 % 2, 2 ** 10)
3.5 3 1 1024

Comparison

==  !=  <  <=  >  >=

Compare values; comparisons can be chained.

Try it
age = 30
print(18 <= age < 65, 3 == 3.0, 'a' < 'b')
True True True

and / or / not

a and b
a or b
not a

Boolean logic that short-circuits and returns one of its operands.

Try it
name = ""
print(name or "anonymous")
print(not name, 0 and 5)
anonymous
True 0

in / not in

x in container

Membership test for strings, lists, sets and dictionary keys.

Try it
print("py" in "python", 4 not in [1, 2, 3], "a" in {"a": 1})
True True True

is / is not

a is b

Identity: are both names the same object? Use it for None.

Try it
x = None
print(x is None, [] is [], [] == [])
True False True

Augmented assignment

+=  -=  *=  /=  //=  %=  **=

Update a variable in place.

Try it
total = 10
total += 5
total *= 2
print(total)
30

Unpacking

a, b = iterable
first, *rest = iterable

Assign several names at once; * collects the remainder.

Try it
a, b = 1, 2
a, b = b, a
first, *rest = [10, 20, 30]
print(a, b, first, rest)
2 1 10 [20, 30]

* and ** spreading

[*a, *b]
{**d1, **d2}
f(*args, **kwargs)

Spread a sequence or mapping into a new one, or into a call.

Try it
a, b = [1, 2], [3]
print([*a, *b])
print({**{"x": 1}, **{"y": 2}})
print(max(*a, *b))
[1, 2, 3]
{'x': 1, 'y': 2}
3

Slicing

seq[start:stop:step]

Take part of a sequence; stop is excluded; negatives count from the end.

Try it
nums = [0, 1, 2, 3, 4, 5]
print(nums[1:4], nums[:2], nums[-2:], nums[::2], nums[::-1])
[1, 2, 3] [0, 1] [4, 5] [0, 2, 4] [5, 4, 3, 2, 1, 0]

Bitwise

&  |  ^  ~  <<  >>

Operate on the binary digits of integers.

Try it
print(6 & 3, 6 | 3, 6 ^ 3, ~6, 1 << 4, 32 >> 2)
2 7 5 -7 16 8

Operator precedence

**  then  * / // %  then  + -

Higher precedence binds first; use parentheses when in doubt.

Try it
print(2 + 3 * 4, (2 + 3) * 4, -2 ** 2)
14 20 -4

Built-in functions

Available everywhere, no import needed. Learn it in a course

print()

print(*values, sep=' ', end='\n')

Write values to the output, separated by sep and followed by end.

Try it
print("a", "b", "c", sep="-")
print("no newline", end="!")
print()
a-b-c
no newline!

len()

len(obj)

Number of items in a string, list, dict, set or tuple.

Try it
print(len("hello"), len([1, 2]), len({"a": 1}))
5 2 1

type()

type(obj)

The type of a value.

Try it
print(type(3), type("x"), type([]))
<class 'int'> <class 'str'> <class 'list'>

isinstance()

isinstance(obj, type_or_tuple)

Is the value of this type (or a subclass of it)?

Try it
print(isinstance(3, int), isinstance(3.0, (int, float)), isinstance("3", int))
True True False

int() / float() / str() / bool()

int(x, base=10)
float(x)
str(x)
bool(x)

Convert between the basic types.

Try it
print(int("42") + 1, int("ff", 16), float("2.5"), str(7) + "!", bool(""), bool("x"))
43 255 2.5 7! False True

list() / tuple() / set() / dict()

list(iterable)
tuple(iterable)
set(iterable)
dict(pairs)

Build a collection from any iterable.

Try it
print(list("abc"), tuple([1, 2]), sorted(set([3, 1, 3])), dict([("a", 1)]))
['a', 'b', 'c'] (1, 2) [1, 3] {'a': 1}

range()

range(stop)
range(start, stop, step)

A lazy sequence of integers; stop is excluded.

Try it
print(list(range(5)), list(range(2, 10, 3)), list(range(5, 0, -1)))
[0, 1, 2, 3, 4] [2, 5, 8] [5, 4, 3, 2, 1]

enumerate()

enumerate(iterable, start=0)

Pair each item with a running index.

Try it
for i, name in enumerate(["Ada", "Bo"], start=1):
    print(i, name)
1 Ada
2 Bo

zip()

zip(*iterables, strict=False)

Walk several iterables in step; stops at the shortest.

Try it
names = ["Ada", "Bo"]
scores = [90, 85]
print(list(zip(names, scores)))
print(dict(zip(names, scores)))
[('Ada', 90), ('Bo', 85)]
{'Ada': 90, 'Bo': 85}

sum()

sum(iterable, start=0)

Add up numbers.

Try it
print(sum([1, 2, 3]), sum(x * x for x in range(4)))
6 14

min() / max()

min(iterable, key=None, default=...)
max(a, b, ...)

Smallest or largest item, optionally compared by a key.

Try it
words = ["pear", "fig", "banana"]
print(min(3, 1, 2), max(words), max(words, key=len))
print(max([], default=0))
1 pear banana
0

sorted()

sorted(iterable, key=None, reverse=False)

A new sorted list; the original is unchanged.

Try it
words = ["pear", "Fig", "apple"]
print(sorted(words))
print(sorted(words, key=str.lower))
print(sorted([3, 1, 2], reverse=True))
['Fig', 'apple', 'pear']
['apple', 'Fig', 'pear']
[3, 2, 1]

reversed()

reversed(sequence)

Iterate a sequence backwards.

Try it
print(list(reversed([1, 2, 3])), "".join(reversed("abc")))
[3, 2, 1] cba

abs() / round() / pow() / divmod()

abs(x)
round(x, ndigits)
pow(base, exp, mod)
divmod(a, b)

Number helpers. round() uses banker's rounding at exact halves.

Try it
print(abs(-5), round(3.14159, 2), round(2.5), pow(2, 10), divmod(17, 5))
5 3.14 2 1024 (3, 2)

any() / all()

any(iterable)
all(iterable)

Is at least one / every item truthy?

Try it
nums = [2, 4, 7]
print(any(n % 2 for n in nums), all(n > 0 for n in nums))
True True

map() / filter()

map(func, iterable)
filter(func, iterable)

Apply a function to every item, or keep items where it is true.

Try it
print(list(map(str.upper, ["a", "b"])))
print(list(filter(lambda n: n > 2, [1, 2, 3, 4])))
['A', 'B']
[3, 4]

input()

input(prompt='')

Read a line typed by the user. It does not work in the browser editors here; use a variable instead.

Try it
name = "Ada"  # in a terminal: name = input("Name? ")
print(f"Hello, {name}")
Hello, Ada

open()

open(path, mode='r', encoding=None)

Open a file. Modes: r read, w write, a append, b binary.

Try it
with open("demo.txt", "w") as f:
    f.write("line 1\nline 2")
with open("demo.txt") as f:
    print(f.read().splitlines())
['line 1', 'line 2']

chr() / ord()

chr(code)
ord(char)

Convert between a character and its Unicode code point.

Try it
print(ord("A"), chr(97), chr(ord("a") + 1))
65 a b

bin() / hex() / oct()

bin(n)
hex(n)
oct(n)

Integer as a binary, hexadecimal or octal string.

Try it
print(bin(10), hex(255), oct(8))
0b1010 0xff 0o10

iter() / next()

iter(iterable)
next(iterator, default)

Get an iterator and pull items from it one at a time.

Try it
it = iter([1, 2])
print(next(it), next(it), next(it, "done"))
1 2 done

getattr() / setattr() / hasattr()

getattr(obj, name, default)
setattr(obj, name, value)
hasattr(obj, name)

Read, set or check an attribute by its name as a string.

Try it
class Box: pass
b = Box()
setattr(b, "size", 3)
print(getattr(b, "size"), hasattr(b, "colour"), getattr(b, "colour", "none"))
3 False none

callable()

callable(obj)

Can this object be called like a function?

Try it
print(callable(len), callable(42))
True False

repr()

repr(obj)

The developer-facing text form of a value, quotes included.

Try it
print(repr("hi"), str("hi"), repr([1, "a"]))
'hi' hi [1, 'a']

id() / hash()

id(obj)
hash(obj)

Object identity, and the hash used by dicts and sets.

Try it
a = [1]
b = a
print(id(a) == id(b), hash(42))
True 42

vars() / dir()

vars(obj)
dir(obj)

An object's attribute dict, or the names it supports.

Try it
class P:
    def __init__(self):
        self.x, self.y = 1, 2
print(vars(P()))
print([n for n in dir("") if n.startswith("is")][:3])
{'x': 1, 'y': 2}
['isalnum', 'isalpha', 'isascii']

help()

help(obj)

Show the documentation for an object in an interactive session.

Try it
print(len.__doc__.splitlines()[0])
Return the number of items in a container.

String methods

Everything you can call on a str. Learn it in a course

upper() / lower() / title() / capitalize()

s.upper()
s.lower()
s.title()
s.capitalize()

Change letter case. Strings never change in place; each returns a new string.

Try it
s = "hello wORLD"
print(s.upper(), s.lower(), s.title(), s.capitalize(), sep=" | ")
HELLO WORLD | hello world | Hello World | Hello world

casefold() / swapcase()

s.casefold()
s.swapcase()

Aggressive lowercasing for comparisons, and inverting case.

Try it
print("Straße".casefold() == "STRASSE".casefold(), "PyThOn".swapcase())
True pYtHoN

strip() / lstrip() / rstrip()

s.strip(chars=None)

Remove whitespace (or given characters) from the ends.

Try it
print(repr("  hi  ".strip()), "xxhixx".strip("x"), repr("  hi  ".rstrip()))
'hi' hi '  hi'

split() / rsplit()

s.split(sep=None, maxsplit=-1)

Break a string into a list. With no sep, splits on any whitespace.

Try it
print("a  b c".split())
print("2026-10-03".split("-"))
print("a,b,c".split(",", 1))
['a', 'b', 'c']
['2026', '10', '03']
['a', 'b,c']

splitlines()

s.splitlines()

Split on line breaks without leaving empty trailing items.

Try it
print("one\ntwo\n".splitlines())
['one', 'two']

join()

sep.join(iterable)

Glue strings together with a separator. Every item must be a string.

Try it
print(", ".join(["a", "b", "c"]))
print("-".join(str(n) for n in [1, 2, 3]))
a, b, c
1-2-3

replace()

s.replace(old, new, count=-1)

Swap every occurrence of a substring (or the first count).

Try it
print("a-b-c".replace("-", "+"), "a-b-c".replace("-", "", 1))
a+b+c ab-c

find() / index() / rfind()

s.find(sub)
s.index(sub)

Position of a substring. find gives -1 if missing; index raises.

Try it
print("banana".find("an"), "banana".rfind("an"), "banana".find("x"))
1 3 -1

count()

s.count(sub)

How many times a substring appears.

Try it
print("banana".count("a"))
3

startswith() / endswith()

s.startswith(prefix)
s.endswith(suffix)

Check the start or end; accepts a tuple of options.

Try it
f = "report.pdf"
print(f.endswith((".pdf", ".docx")), f.startswith("rep"))
True True

removeprefix() / removesuffix()

s.removeprefix(prefix)
s.removesuffix(suffix)

Drop an exact prefix or suffix if present (3.9+).

Try it
print("v1.2".removeprefix("v"), "data.csv".removesuffix(".csv"))
1.2 data

isdigit() / isalpha() / isalnum() / isspace()

s.isdigit()
s.isalpha()
s.isalnum()
s.isspace()

Test what kind of characters a string contains.

Try it
print("123".isdigit(), "abc".isalpha(), "a1".isalnum(), "  ".isspace(), "".isdigit())
True True True True False

isupper() / islower()

s.isupper()
s.islower()

Are all cased letters upper or lower case?

Try it
print("ABC".isupper(), "abc1".islower())
True True

center() / ljust() / rjust() / zfill()

s.center(width, fill)
s.ljust(width)
s.rjust(width)
s.zfill(width)

Pad a string to a width.

Try it
print("[" + "hi".center(6, "*") + "]", "[" + "hi".ljust(4) + "]", "42".zfill(5))
[**hi**] [hi  ] 00042

partition() / rpartition()

s.partition(sep)

Split once into (before, sep, after).

Try it
print("key=value=x".partition("="))
print("a.b.c".rpartition("."))
('key', '=', 'value=x')
('a.b', '.', 'c')

encode() / decode()

s.encode('utf-8')
b.decode('utf-8')

Convert between text and bytes.

Try it
b = "café".encode("utf-8")
print(b, b.decode("utf-8"))
b'caf\xc3\xa9' café

Indexing & slicing

s[i]
s[start:stop:step]

Characters by position; [::-1] reverses.

Try it
s = "python"
print(s[0], s[-1], s[1:4], s[::-1])
p n yth nohtyp

Escape sequences & raw strings

"\n"  "\t"  "\\"  r"C:\path"

Backslash codes for special characters; r'' turns them off.

Try it
print("a\tb")
print(r"C:\new\table")
a	b
C:\new\table

Multi-line strings

"""line one
line two"""

Triple quotes keep line breaks.

Try it
text = """first
second"""
print(text.splitlines())
['first', 'second']

str.maketrans() / translate()

s.translate(str.maketrans(from, to, delete))

Replace or delete many characters in one pass.

Try it
table = str.maketrans("ae", "43", "!")
print("hello there!".translate(table))
h3llo th3r3

f-strings & formatting

The format mini-language inside {}. Learn it in a course

f-string basics

f"text {expression}"

Any expression inside {} is evaluated and inserted.

Try it
name, n = "Ada", 3
print(f"{name} has {n * 2} points")
Ada has 6 points

Debug specifier =

f"{expr=}"

Print the expression and its value together (3.8+).

Try it
price = 9.5
print(f"{price=}", f"{price * 2 = }")
price=9.5 price * 2 = 19.0

!r and !s conversions

f"{value!r}"

Use repr() instead of str(), which shows quotes on strings.

Try it
word = "hi"
print(f"{word} vs {word!r}")
hi vs 'hi'

Decimal places :.Nf

f"{x:.2f}"

Fixed number of decimal places.

Try it
print(f"{3.14159:.2f}", f"{2:.3f}")
3.14 2.000

Thousands separator :,

f"{n:,}"   f"{n:_}"

Group digits with commas or underscores.

Try it
print(f"{1234567:,}", f"{1234567.891:,.2f}", f"{1234567:_}")
1,234,567 1,234,567.89 1_234_567

Percent :%

f"{ratio:.1%}"

Multiply by 100 and add a percent sign.

Try it
print(f"{0.4567:.1%}", f"{1/3:.0%}")
45.7% 33%

Width & alignment

f"{x:<10}"  f"{x:>10}"  f"{x:^10}"

Pad to a width, aligned left, right or centred.

Try it
print(f"[{'ab':<6}]", f"[{'ab':>6}]", f"[{'ab':^6}]", f"[{'ab':*^6}]")
[ab    ] [    ab] [  ab  ] [**ab**]

Zero padding :0N

f"{n:05}"   f"{x:08.3f}"

Pad numbers with leading zeros.

Try it
print(f"{42:05}", f"{3.14159:08.3f}")
00042 0003.142

Signs :+

f"{n:+}"

Always show the sign.

Try it
print(f"{5:+}", f"{-5:+}")
+5 -5

Number bases :b :o :x

f"{n:b}"  f"{n:o}"  f"{n:x}"  f"{n:#x}"

Binary, octal and hex; # adds the 0b/0o/0x prefix.

Try it
print(f"{10:b}", f"{8:o}", f"{255:x}", f"{255:#X}")
1010 10 ff 0XFF

Scientific notation :e

f"{x:.2e}"

Exponent form for very large or small numbers.

Try it
print(f"{123456789:.2e}", f"{0.000123:.1e}")
1.23e+08 1.2e-04

Dates in f-strings

f"{date:%Y-%m-%d}"

strftime codes work directly inside the braces.

Try it
from datetime import date
d = date(2026, 3, 9)
print(f"{d:%d %B %Y}", f"{d:%a %d/%m}")
09 March 2026 Mon 09/03

Nested format specs

f"{x:{width}.{precision}f}"

Fill in the width or precision from variables.

Try it
width, prec = 10, 3
print(f"[{3.14159:{width}.{prec}f}]")
[     3.142]

str.format()

"{} {name}".format(a, name=b)

The pre-f-string method, still used for templates stored as data.

Try it
template = "Hi {name}, you owe {amount:.2f}"
print(template.format(name="Bo", amount=12.5))
Hi Bo, you owe 12.50

% formatting

"%s is %d" % (name, n)

The oldest style; you will see it in older code and logging.

Try it
print("%s is %d years old" % ("Ada", 36))
Ada is 36 years old

List methods

Ordered, changeable sequences. Learn it in a course

append()

lst.append(item)

Add one item to the end.

Try it
nums = [1, 2]
nums.append(3)
print(nums)
[1, 2, 3]

extend()

lst.extend(iterable)

Add every item from another iterable.

Try it
nums = [1]
nums.extend([2, 3])
print(nums)
[1, 2, 3]

insert()

lst.insert(index, item)

Put an item at a position, shifting the rest right.

Try it
letters = ["a", "c"]
letters.insert(1, "b")
print(letters)
['a', 'b', 'c']

remove()

lst.remove(value)

Delete the first item equal to value; ValueError if absent.

Try it
pets = ["cat", "dog", "cat"]
pets.remove("cat")
print(pets)
['dog', 'cat']

pop()

lst.pop(index=-1)

Remove and return an item, the last one by default.

Try it
stack = [1, 2, 3]
top = stack.pop()
first = stack.pop(0)
print(top, first, stack)
3 1 [2]

clear()

lst.clear()

Remove everything.

Try it
nums = [1, 2]
nums.clear()
print(nums)
[]

index() / count()

lst.index(value)
lst.count(value)

Position of the first match, or how many times it appears.

Try it
votes = ["y", "n", "y"]
print(votes.index("n"), votes.count("y"))
1 2

sort()

lst.sort(key=None, reverse=False)

Sort in place and return None. Use sorted() for a new list.

Try it
people = [("Bo", 31), ("Ada", 36)]
people.sort(key=lambda p: p[1], reverse=True)
print(people)
[('Ada', 36), ('Bo', 31)]

reverse()

lst.reverse()

Reverse in place.

Try it
nums = [1, 2, 3]
nums.reverse()
print(nums)
[3, 2, 1]

copy()

lst.copy()   lst[:]

A shallow copy, so changing it leaves the original alone.

Try it
a = [1, 2]
b = a.copy()
b.append(3)
print(a, b)
[1, 2] [1, 2, 3]

List comprehension

[expr for x in iterable if cond]

Build a list in one expression, optionally filtered.

Try it
print([n * n for n in range(6) if n % 2 == 0])
[0, 4, 16]

Nested comprehension

[expr for a in A for b in B]

Loops read left to right, outer first.

Try it
print([f"{r}{c}" for r in "AB" for c in "12"])
['A1', 'A2', 'B1', 'B2']

Slice assignment

lst[i:j] = iterable

Replace, insert or delete a whole range at once.

Try it
nums = [0, 1, 2, 3, 4]
nums[1:3] = [9]
print(nums)
[0, 9, 3, 4]

2D lists

grid = [[0] * cols for _ in range(rows)]

Lists of lists. Build rows with a comprehension so they are separate objects.

Try it
grid = [[0] * 3 for _ in range(2)]
grid[0][1] = 5
print(grid)
[[0, 5, 0], [0, 0, 0]]

List as a stack / queue

lst.append() + lst.pop()
collections.deque

Lists are fast stacks; use deque for queues.

Try it
from collections import deque
q = deque([1, 2])
q.append(3)
print(q.popleft(), list(q))
1 [2, 3]

Dictionary methods

Key-value lookup tables. Learn it in a course

Create & access

d = {key: value}
d[key]

Look up by key; a missing key raises KeyError.

Try it
ages = {"Ada": 36, "Bo": 31}
print(ages["Ada"])
ages["Cy"] = 28
print(ages)
36
{'Ada': 36, 'Bo': 31, 'Cy': 28}

get()

d.get(key, default=None)

Look up safely, with a fallback for missing keys.

Try it
stock = {"apple": 3}
print(stock.get("apple"), stock.get("pear"), stock.get("pear", 0))
3 None 0

keys() / values() / items()

d.keys()
d.values()
d.items()

Views of the keys, values or (key, value) pairs.

Try it
prices = {"tea": 2, "cake": 4}
for item, price in prices.items():
    print(item, price)
print(list(prices), sum(prices.values()))
tea 2
cake 4
['tea', 'cake'] 6

update()

d.update(other)

Merge another mapping in, overwriting matching keys.

Try it
conf = {"debug": False, "port": 80}
conf.update({"debug": True})
print(conf)
{'debug': True, 'port': 80}

Merge | and |=

d1 | d2
d1 |= d2

Combine two dicts into a new one; the right side wins (3.9+).

Try it
base = {"a": 1, "b": 2}
print(base | {"b": 9, "c": 3})
{'a': 1, 'b': 9, 'c': 3}

pop() / popitem()

d.pop(key, default)
d.popitem()

Remove a key and return its value; popitem removes the last added.

Try it
d = {"a": 1, "b": 2}
print(d.pop("a"), d.pop("z", None), d.popitem(), d)
1 None ('b', 2) {}

setdefault()

d.setdefault(key, default)

Return the value, inserting the default first if the key is missing.

Try it
groups = {}
groups.setdefault("fruit", []).append("apple")
groups.setdefault("fruit", []).append("pear")
print(groups)
{'fruit': ['apple', 'pear']}

in / del

key in d
del d[key]

Check for a key, or remove one.

Try it
d = {"a": 1}
print("a" in d, 1 in d)
del d["a"]
print(d)
True False
{}

Dict comprehension

{k: v for x in iterable}

Build a dict in one expression.

Try it
words = ["fig", "apple"]
print({w: len(w) for w in words})
{'fig': 3, 'apple': 5}

fromkeys()

dict.fromkeys(keys, value=None)

A new dict with every key set to the same value.

Try it
print(dict.fromkeys(["a", "b"], 0))
{'a': 0, 'b': 0}

Sort a dict by value

sorted(d.items(), key=lambda kv: kv[1])

Dicts keep insertion order; sort their items to reorder.

Try it
scores = {"Ada": 90, "Bo": 72, "Cy": 85}
print(sorted(scores.items(), key=lambda kv: kv[1], reverse=True))
print(max(scores, key=scores.get))
[('Ada', 90), ('Cy', 85), ('Bo', 72)]
Ada

Counting pattern

d[k] = d.get(k, 0) + 1

The one-line accumulator for tallies.

Try it
counts = {}
for ch in "banana":
    counts[ch] = counts.get(ch, 0) + 1
print(counts)
{'b': 1, 'a': 3, 'n': 2}

Nested dicts

d[outer][inner]

Dicts of dicts, the shape of most JSON.

Try it
user = {"name": "Ada", "address": {"city": "London"}}
print(user["address"]["city"])
print(user.get("phone", {}).get("mobile", "none"))
London
none

copy()

d.copy()

A shallow copy of the dict.

Try it
a = {"x": 1}
b = a.copy()
b["x"] = 2
print(a, b)
{'x': 1} {'x': 2}

Sets & tuples

Unique collections and fixed records. Learn it in a course

Create a set

{1, 2, 3}
set(iterable)

Unordered, unique items. {} alone is an empty dict, so use set().

Try it
print(set([3, 1, 3, 2]), set(), type({}))
{1, 2, 3} set() <class 'dict'>

add() / update()

s.add(item)
s.update(iterable)

Add one item, or many.

Try it
s = {1}
s.add(2)
s.update([3, 4, 1])
print(s)
{1, 2, 3, 4}

remove() / discard()

s.remove(item)
s.discard(item)

Delete an item; remove raises if missing, discard does not.

Try it
s = {1, 2}
s.discard(9)
s.remove(1)
print(s)
{2}

Union | and intersection &

a | b
a & b

Everything in either set, or only what is in both.

Try it
a, b = {1, 2, 3}, {3, 4}
print(a | b, a & b)
{1, 2, 3, 4} {3}

Subset <= and superset >=

a <= b
a >= b

Is every item of one set inside the other?

Try it
print({1, 2} <= {1, 2, 3}, {1, 2, 3} >= {4})
True False

Set comprehension

{expr for x in iterable}

Build a set of unique results.

Try it
words = ["Hi", "hi", "HEY"]
print(sorted({w.lower() for w in words}))
['hey', 'hi']

frozenset()

frozenset(iterable)

An immutable set that can be a dict key or live inside another set.

Try it
fs = frozenset([1, 2])
print({fs: 'pair'}[frozenset([2, 1])])
pair

Remove duplicates, keep order

list(dict.fromkeys(items))

Sets lose order; dict keys keep it.

Try it
print(list(dict.fromkeys(["b", "a", "b", "c", "a"])))
['b', 'a', 'c']

Tuples

t = (1, 2)
t = 1,
t = (1,)

Fixed-size, immutable sequences. A single item needs a trailing comma.

Try it
point = (3, 4)
x, y = point
print(x, y, type((1)), type((1,)))
3 4 <class 'int'> <class 'tuple'>

namedtuple

namedtuple('Name', 'field1 field2')

A tuple whose items also have names.

Try it
from collections import namedtuple
Point = namedtuple("Point", "x y")
p = Point(3, 4)
print(p.x, p[1], p)
3 4 Point(x=3, y=4)

Functions

Parameters, return values, closures and decorators. Learn it in a course

Default arguments

def f(a, b=10):

Parameters with a fallback value. Never use a mutable default like [].

Try it
def greet(name, punct="!"):
    return f"Hi {name}{punct}"
print(greet("Ada"), greet("Bo", "?"))
Hi Ada! Hi Bo?

Keyword arguments

f(name=value)

Pass arguments by name, in any order.

Try it
def box(w, h):
    return f"{w}x{h}"
print(box(h=2, w=5))
5x2

*args

def f(*args):

Collect any number of positional arguments into a tuple.

Try it
def total(*nums):
    return sum(nums)
print(total(1, 2, 3))
6

**kwargs

def f(**kwargs):

Collect any number of keyword arguments into a dict.

Try it
def tag(**attrs):
    return " ".join(f'{k}="{v}"' for k, v in attrs.items())
print(tag(id="main", lang="en"))
id="main" lang="en"

Keyword-only and positional-only

def f(pos, /, normal, *, kw):

Parameters before / must be positional; after * must be named.

Try it
def connect(host, /, port=80, *, secure=False):
    return f"{host}:{port} secure={secure}"
print(connect("example.com", secure=True))
example.com:80 secure=True

Return several values

return a, b

Returning a tuple, unpacked by the caller.

Try it
def min_max(nums):
    return min(nums), max(nums)
lo, hi = min_max([4, 1, 9])
print(lo, hi)
1 9

Type hints

def f(x: int) -> str:

Document expected types. Python does not enforce them at run time.

Try it
def label(qty: int, unit: str = "item") -> str:
    return f"{qty} {unit}s"
print(label(3), label.__annotations__["return"])
3 items <class 'str'>

Closures

def outer():
    def inner(): ...
    return inner

An inner function remembers the variables around it.

Try it
def multiplier(n):
    def times(x):
        return x * n
    return times
triple = multiplier(3)
print(triple(5))
15

Decorators

@decorator
def f(): ...

Wrap a function to add behaviour without changing it.

Try it
def shout(fn):
    def wrapper(*args):
        return fn(*args).upper() + "!"
    return wrapper

@shout
def hello(name):
    return f"hello {name}"

print(hello("ada"))
HELLO ADA!

Recursion

def f(n):
    if base: return ...
    return f(smaller)

A function that calls itself on a smaller input until a base case.

Try it
def factorial(n):
    return 1 if n <= 1 else n * factorial(n - 1)
print(factorial(5))
120

Generator expression

(expr for x in iterable)

Like a list comprehension but lazy, so it uses almost no memory.

Try it
print(sum(n * n for n in range(1_000)))
332833500

Functions are objects

f.__name__
funcs = [f, g]

Store functions in variables, lists and dicts, and pass them around.

Try it
ops = {"add": lambda a, b: a + b, "mul": lambda a, b: a * b}
print(ops["mul"](3, 4), len.__name__)
12 len

Classes & OOP

Objects, inheritance, properties and dataclasses. Learn it in a course

__init__ and self

class C:
    def __init__(self, x):
        self.x = x

The initialiser sets up each new object; self is that object.

Try it
class Account:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

acct = Account("Ada", 100)
print(acct.owner, acct.balance)
Ada 100

Methods

def method(self, ...):

Functions defined in a class that act on an instance.

Try it
class Counter:
    def __init__(self):
        self.n = 0
    def tick(self):
        self.n += 1
        return self.n

c = Counter()
c.tick()
print(c.tick())
2

Class attributes

class C:
    shared = value

Shared by every instance, unlike attributes set on self.

Try it
class Dog:
    species = "canine"
    def __init__(self, name):
        self.name = name

print(Dog("Rex").species, Dog.species)
canine canine

Inheritance & super()

class Child(Parent):
    def __init__(self):
        super().__init__()

A subclass reuses and extends its parent.

Try it
class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        return "..."

class Cat(Animal):
    def speak(self):
        return f"{self.name} says meow"

print(Cat("Tom").speak(), isinstance(Cat("Tom"), Animal))
Tom says meow True

@property

@property
def name(self): ...

A method you read like an attribute, often computed or validated.

Try it
class Circle:
    def __init__(self, r):
        self.r = r
    @property
    def area(self):
        return round(3.14159 * self.r ** 2, 1)

print(Circle(2).area)
12.6

@classmethod / @staticmethod

@classmethod
def f(cls, ...):
@staticmethod
def g(...):

classmethod receives the class (good for alternative constructors); staticmethod receives nothing.

Try it
class Temp:
    def __init__(self, c):
        self.c = c
    @classmethod
    def from_f(cls, f):
        return cls(round((f - 32) / 1.8, 1))
    @staticmethod
    def is_freezing(c):
        return c <= 0

print(Temp.from_f(212).c, Temp.is_freezing(-3))
100.0 True

@dataclass

@dataclass
class C:
    field: type = default

Generates __init__, __repr__ and __eq__ from annotated fields.

Try it
from dataclasses import dataclass, field

@dataclass
class Item:
    name: str
    price: float
    tags: list = field(default_factory=list)

print(Item("pen", 1.5))
print(Item("pen", 1.5) == Item("pen", 1.5))
Item(name='pen', price=1.5, tags=[])
True

Enum

class Color(Enum):
    RED = 1

A fixed set of named constants.

Try it
from enum import Enum

class Status(Enum):
    ACTIVE = "active"
    BANNED = "banned"

print(Status.ACTIVE, Status("banned").name, [s.value for s in Status])
Status.ACTIVE BANNED ['active', 'banned']

Private by convention

self._internal
self.__mangled

A leading _ means internal; __ triggers name mangling.

Try it
class Safe:
    def __init__(self):
        self._hint = "internal"
        self.__code = 1234

s = Safe()
print(s._hint, hasattr(s, "__code"), s._Safe__code)
internal False 1234

Abstract base classes

class Base(ABC):
    @abstractmethod
    def f(self): ...

Force subclasses to implement certain methods.

Try it
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self): ...

class Square(Shape):
    def __init__(self, s):
        self.s = s
    def area(self):
        return self.s ** 2

print(Square(3).area())
try:
    Shape()
except TypeError:
    print("cannot instantiate an abstract class")
9
cannot instantiate an abstract class

Dunder methods

Hooks that let your objects work with built-in syntax. Learn it in a course

__repr__ / __str__

def __repr__(self): ...
def __str__(self): ...

repr is for developers (and debuggers); str is for print().

Try it
class Money:
    def __init__(self, amount):
        self.amount = amount
    def __repr__(self):
        return f"Money({self.amount})"
    def __str__(self):
        return f"£{self.amount:.2f}"

m = Money(5)
print(m, repr(m), [m])
£5.00 Money(5) [Money(5)]

__eq__ / __lt__

def __eq__(self, other): ...
def __lt__(self, other): ...

Define == and < so objects compare and sort by value.

Try it
class Version:
    def __init__(self, major, minor):
        self.v = (major, minor)
    def __eq__(self, o):
        return self.v == o.v
    def __lt__(self, o):
        return self.v < o.v

print(Version(1, 2) < Version(1, 10), Version(2, 0) == Version(2, 0))
print([v.v for v in sorted([Version(2, 0), Version(1, 5)])])
True True
[(1, 5), (2, 0)]

__len__ / __getitem__

def __len__(self): ...
def __getitem__(self, i): ...

Support len(obj) and obj[i] (which also makes it iterable).

Try it
class Deck:
    def __init__(self):
        self.cards = ["A", "K", "Q"]
    def __len__(self):
        return len(self.cards)
    def __getitem__(self, i):
        return self.cards[i]

d = Deck()
print(len(d), d[0], list(d))
3 A ['A', 'K', 'Q']

__contains__

def __contains__(self, item): ...

Support the in operator.

Try it
class Range:
    def __init__(self, lo, hi):
        self.lo, self.hi = lo, hi
    def __contains__(self, x):
        return self.lo <= x <= self.hi

print(5 in Range(1, 10), 50 in Range(1, 10))
True False

__iter__ / __next__

def __iter__(self): ...
def __next__(self): ...

Make an object iterable; raise StopIteration to finish.

Try it
class Countdown:
    def __init__(self, n):
        self.n = n
    def __iter__(self):
        return self
    def __next__(self):
        if self.n == 0:
            raise StopIteration
        self.n -= 1
        return self.n + 1

print(list(Countdown(3)))
[3, 2, 1]

__add__ and arithmetic

def __add__(self, other): ...

Define +, -, * and friends (__sub__, __mul__, __truediv__…).

Try it
class Vec:
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __add__(self, o):
        return Vec(self.x + o.x, self.y + o.y)
    def __repr__(self):
        return f"Vec({self.x}, {self.y})"

print(Vec(1, 2) + Vec(3, 4))
Vec(4, 6)

__call__

def __call__(self, ...): ...

Let an instance be called like a function.

Try it
class Adder:
    def __init__(self, n):
        self.n = n
    def __call__(self, x):
        return x + self.n

add5 = Adder(5)
print(add5(10))
15

__enter__ / __exit__

def __enter__(self): ...
def __exit__(self, *exc): ...

Make an object usable in a with block.

Try it
class Timer:
    def __enter__(self):
        print("start")
        return self
    def __exit__(self, *exc):
        print("stop")

with Timer():
    print("working")
start
working
stop

__bool__

def __bool__(self): ...

Decide whether the object counts as true in an if.

Try it
class Cart:
    def __init__(self, items):
        self.items = items
    def __bool__(self):
        return bool(self.items)

print("has items" if Cart([1]) else "empty", bool(Cart([])))
has items False

__hash__

def __hash__(self): ...

Needed to put custom objects in sets or use them as dict keys alongside __eq__.

Try it
class Tag:
    def __init__(self, name):
        self.name = name
    def __eq__(self, o):
        return self.name == o.name
    def __hash__(self):
        return hash(self.name)

print(len({Tag('a'), Tag('a'), Tag('b')}))
2

Exceptions

What each common error means and how to handle it. Learn it in a course

ValueError

raised for the right type but a bad value

For example, converting text that is not a number.

Try it
try:
    int("abc")
except ValueError as e:
    print("ValueError:", e)
ValueError: invalid literal for int() with base 10: 'abc'

TypeError

raised when types do not fit the operation

For example, adding a string to a number.

Try it
try:
    "age: " + 30
except TypeError as e:
    print("TypeError:", e)
TypeError: can only concatenate str (not "int") to str

KeyError

raised for a missing dictionary key

Use .get() or check with in first.

Try it
try:
    {"a": 1}["b"]
except KeyError as e:
    print("KeyError:", e)
KeyError: 'b'

IndexError

raised for a position past the end

Lists are indexed from 0 to len - 1.

Try it
try:
    [1, 2, 3][3]
except IndexError as e:
    print("IndexError:", e)
IndexError: list index out of range

ZeroDivisionError

raised when dividing by zero

Check the divisor before dividing.

Try it
try:
    10 / 0
except ZeroDivisionError as e:
    print("ZeroDivisionError:", e)
ZeroDivisionError: division by zero

AttributeError

raised for a missing attribute or method

Often a typo, or calling a method on None.

Try it
try:
    (42).upper()
except AttributeError as e:
    print("AttributeError:", e)
AttributeError: 'int' object has no attribute 'upper'

NameError

raised for a name that was never defined

Usually a typo or using a variable before assigning it.

Try it
try:
    print(totl)
except NameError as e:
    print("NameError:", e)
NameError: name 'totl' is not defined

FileNotFoundError

raised when opening a path that does not exist

A subclass of OSError.

Try it
try:
    open("missing.txt")
except FileNotFoundError as e:
    print("FileNotFoundError:", e.strerror)
FileNotFoundError: No such file or directory

ModuleNotFoundError

raised when an import cannot be found

The package is not installed, or the name is misspelt.

Try it
try:
    import not_a_real_module
except ModuleNotFoundError as e:
    print("ModuleNotFoundError:", e)
ModuleNotFoundError: No module named 'not_a_real_module'

StopIteration

raised by next() when an iterator is exhausted

for loops handle it for you.

Try it
it = iter([])
try:
    next(it)
except StopIteration:
    print("StopIteration: nothing left")
StopIteration: nothing left

RecursionError

raised when recursion goes too deep

A recursive function without a reachable base case.

Try it
def forever(n):
    return forever(n + 1)
try:
    forever(0)
except RecursionError:
    print("RecursionError: maximum recursion depth exceeded")
RecursionError: maximum recursion depth exceeded

Catch several types

except (TypeError, ValueError) as e:

One handler for a group of errors.

Try it
for raw in ["5", "x", None]:
    try:
        print(int(raw) * 2)
    except (TypeError, ValueError) as e:
        print("skipped", type(e).__name__)
10
skipped ValueError
skipped TypeError

Custom exceptions

class MyError(Exception): ...

Name your own error types so callers can catch them precisely.

Try it
class InsufficientFunds(Exception):
    pass

try:
    raise InsufficientFunds("balance too low")
except InsufficientFunds as e:
    print(type(e).__name__, "-", e)
InsufficientFunds - balance too low

raise … from

raise NewError(...) from original

Re-raise as a clearer error while keeping the original cause.

Try it
try:
    try:
        int("x")
    except ValueError as e:
        raise RuntimeError("bad config") from e
except RuntimeError as e:
    print(e, "| caused by", type(e.__cause__).__name__)
bad config | caused by ValueError

Exception hierarchy

BaseException > Exception > ArithmeticError > ZeroDivisionError

Catching a parent class catches all of its subclasses.

Try it
print(issubclass(ZeroDivisionError, ArithmeticError), issubclass(KeyError, LookupError))
True True

Iteration, itertools & functools

Loop helpers and functional tools. Learn it in a course

itertools.chain()

chain(*iterables)

Treat several iterables as one.

Try it
from itertools import chain
print(list(chain([1, 2], (3,), range(4, 6))))
[1, 2, 3, 4, 5]

itertools.product()

product(*iterables, repeat=1)

Every combination of one item from each input (nested loops).

Try it
from itertools import product
print(list(product("ab", [1, 2])))
[('a', 1), ('a', 2), ('b', 1), ('b', 2)]

itertools.permutations()

permutations(iterable, r)

Every ordering of r items.

Try it
from itertools import permutations
print(["".join(p) for p in permutations("abc", 2)])
['ab', 'ac', 'ba', 'bc', 'ca', 'cb']

itertools.combinations()

combinations(iterable, r)

Every selection of r items where order does not matter.

Try it
from itertools import combinations
print(list(combinations([1, 2, 3], 2)))
[(1, 2), (1, 3), (2, 3)]

itertools.groupby()

groupby(sorted_iterable, key)

Group consecutive items with the same key; sort first.

Try it
from itertools import groupby
words = sorted(["apple", "avocado", "banana", "blueberry", "cherry"])
for letter, group in groupby(words, key=lambda w: w[0]):
    print(letter, list(group))
a ['apple', 'avocado']
b ['banana', 'blueberry']
c ['cherry']

itertools.islice() / count()

islice(iterable, stop)
count(start, step)

Slice any iterator, or count forever.

Try it
from itertools import islice, count
print(list(islice(count(10, 5), 4)))
[10, 15, 20, 25]

itertools.accumulate()

accumulate(iterable, func=operator.add)

Running totals (or running anything).

Try it
from itertools import accumulate
print(list(accumulate([1, 2, 3, 4])), list(accumulate([3, 1, 4], max)))
[1, 3, 6, 10] [3, 3, 4]

itertools.pairwise()

pairwise(iterable)

Overlapping pairs of neighbours (3.10+).

Try it
from itertools import pairwise
print([b - a for a, b in pairwise([1, 4, 9, 16])])
[3, 5, 7]

functools.reduce()

reduce(func, iterable, initial)

Fold a sequence down to one value.

Try it
from functools import reduce
print(reduce(lambda a, b: a * b, range(1, 6)))
120

functools.partial()

partial(func, *args, **kwargs)

Pre-fill some arguments of a function.

Try it
from functools import partial
binary = partial(int, base=2)
print(binary("1010"))
10

functools.lru_cache / cache

@lru_cache(maxsize=128)
@cache

Remember results so repeated calls are instant.

Try it
from functools import cache

@cache
def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)

print(fib(80))
23416728348467685

operator module

operator.itemgetter / attrgetter

Ready-made key functions, faster than lambdas.

Try it
from operator import itemgetter
rows = [("Bo", 31), ("Ada", 36)]
print(sorted(rows, key=itemgetter(1)))
[('Bo', 31), ('Ada', 36)]

Files & paths

Reading, writing and working with paths. Learn it in a course

Read a whole file

with open(path) as f:
    text = f.read()

The with block closes the file for you.

Try it
with open("poem.txt", "w") as f:
    f.write("roses\nviolets\n")
with open("poem.txt") as f:
    print(repr(f.read()))
'roses\nviolets\n'

Read line by line

for line in f:

Memory-friendly for large files; strip the newline yourself.

Try it
with open("poem.txt", "w") as f:
    f.write("roses\nviolets\n")
with open("poem.txt") as f:
    for n, line in enumerate(f, 1):
        print(n, line.strip())
1 roses
2 violets

Write and append

open(path, 'w')
open(path, 'a')

w replaces the file; a adds to the end.

Try it
with open("log.txt", "w") as f:
    f.write("first\n")
with open("log.txt", "a") as f:
    f.write("second\n")
with open("log.txt") as f:
    print(f.read().splitlines())
['first', 'second']

pathlib.Path

Path('folder') / 'file.txt'

Object-oriented paths that join with /.

Try it
from pathlib import Path
p = Path("data") / "reports" / "q1.csv"
print(p, p.name, p.stem, p.suffix, p.parent)
data/reports/q1.csv q1.csv q1 .csv data/reports

Path.read_text() / write_text()

Path(p).read_text()
Path(p).write_text(s)

One-line file reads and writes.

Try it
from pathlib import Path
Path("hello.txt").write_text("hi there")
print(Path("hello.txt").read_text(), Path("hello.txt").exists())
hi there True

List files with glob

Path('.').glob('*.txt')

Find files by pattern.

Try it
from pathlib import Path
for name in ["a.txt", "b.txt", "c.csv"]:
    Path(name).write_text("")
print(sorted(p.name for p in Path(".").glob("*.txt")))
['a.txt', 'b.txt']

CSV

csv.reader / csv.DictReader / csv.writer

Read and write comma-separated data safely, quotes and all.

Try it
import csv, io
data = io.StringIO("name,score\nAda,90\nBo,72\n")
for row in csv.DictReader(data):
    print(row["name"], int(row["score"]))
Ada 90
Bo 72

JSON files

json.dump(obj, f)
json.load(f)

Save and load Python data as JSON.

Try it
import json
with open("save.json", "w") as f:
    json.dump({"level": 3, "items": ["key"]}, f)
with open("save.json") as f:
    print(json.load(f))
{'level': 3, 'items': ['key']}

os.path helpers

os.path.join / splitext / basename

The older, string-based path functions.

Try it
import os
print(os.path.join("a", "b.txt"), os.path.splitext("photo.jpg"), os.path.basename("/x/y/z.py"))
a/b.txt ('photo', '.jpg') z.py

Standard library

The modules worth knowing, one import away. Learn it in a course

math

import math

Square roots, rounding, constants and more.

Try it
import math
print(math.sqrt(16), math.floor(2.7), math.ceil(2.1), round(math.pi, 4))
print(math.gcd(12, 18), math.isclose(0.1 + 0.2, 0.3))
4.0 2 3 3.1416
6 True

random

import random

Pseudo-random numbers. seed() makes runs repeatable.

Try it
import random
random.seed(42)
print(random.randint(1, 6), random.choice(["a", "b", "c"]))
items = [1, 2, 3, 4]
random.shuffle(items)
print(items, round(random.random(), 3))
6 a
[4, 2, 3, 1] 0.245

statistics

import statistics

Mean, median, mode and spread.

Try it
import statistics as st
data = [2, 4, 4, 5, 7, 9]
print(st.mean(data), st.median(data), st.mode(data), round(st.stdev(data), 2))
5.166666666666667 4.5 4 2.48

datetime: dates and times

from datetime import date, datetime, timedelta

Create, compare and do arithmetic on dates.

Try it
from datetime import date, timedelta
d = date(2026, 1, 31)
print(d + timedelta(days=1), (date(2026, 12, 25) - d).days, d.weekday())
2026-02-01 328 5

datetime: parse and format

datetime.strptime(text, fmt)
dt.strftime(fmt)

Turn text into a datetime and back. %Y year, %m month, %d day, %H:%M time.

Try it
from datetime import datetime
dt = datetime.strptime("2026-03-09 14:30", "%Y-%m-%d %H:%M")
print(dt.strftime("%A %d %B, %I:%M %p"))
print(dt.isoformat())
Monday 09 March, 02:30 PM
2026-03-09T14:30:00

json

json.dumps(obj)
json.loads(text)

Convert between Python objects and JSON text.

Try it
import json
text = json.dumps({"name": "Ada", "tags": ["x"], "ok": True})
print(text)
print(json.loads(text)["tags"], json.dumps({"b": 1, "a": 2}, sort_keys=True, indent=None))
{"name": "Ada", "tags": ["x"], "ok": true}
['x'] {"a": 2, "b": 1}

re: search and match

re.search(pattern, text)
m.group()

Find the first match of a regular expression.

Try it
import re
m = re.search(r"(\d{4})-(\d{2})", "Due 2026-10, ok")
print(m.group(), m.group(1), m.span())
2026-10 2026 (4, 11)

re: findall, sub, split

re.findall(p, s)
re.sub(p, repl, s)
re.split(p, s)

All matches, find and replace, or split on a pattern.

Try it
import re
text = "Call 555-1234 or 555-9876"
print(re.findall(r"\d{3}-\d{4}", text))
print(re.sub(r"\d", "#", "pin 4821"))
print(re.split(r"[,;]\s*", "a, b;c"))
['555-1234', '555-9876']
pin ####
['a', 'b', 'c']

collections.Counter

Counter(iterable)

Count things, then ask for the most common.

Try it
from collections import Counter
c = Counter("mississippi")
print(c.most_common(2), c["s"], c["z"])
[('i', 4), ('s', 4)] 4 0

collections.defaultdict

defaultdict(factory)

A dict that creates missing values automatically.

Try it
from collections import defaultdict
by_letter = defaultdict(list)
for w in ["ant", "bee", "ape"]:
    by_letter[w[0]].append(w)
print(dict(by_letter))
{'a': ['ant', 'ape'], 'b': ['bee']}

collections.deque

deque(iterable, maxlen=None)

Fast appends and pops at both ends; maxlen keeps the last N.

Try it
from collections import deque
recent = deque(maxlen=3)
for n in range(5):
    recent.append(n)
print(list(recent))
[2, 3, 4]

heapq

heapq.heappush / heappop / nsmallest

A priority queue: always pop the smallest item.

Try it
import heapq
tasks = []
for p in [5, 1, 3]:
    heapq.heappush(tasks, p)
print(heapq.heappop(tasks), heapq.nlargest(2, [4, 9, 1, 7]))
1 [9, 7]

bisect

bisect.bisect_left(sorted_list, x)
bisect.insort(lst, x)

Binary search and sorted insertion.

Try it
import bisect
grades = [60, 70, 80, 90]
print(bisect.bisect(grades, 85), 'FDCBA'[bisect.bisect(grades, 85)])
nums = [1, 3, 5]
bisect.insort(nums, 4)
print(nums)
3 B
[1, 3, 4, 5]

decimal / fractions

Decimal('0.1')
Fraction(1, 3)

Exact decimal money maths, and exact fractions.

Try it
from decimal import Decimal
from fractions import Fraction
print(0.1 + 0.2, Decimal("0.1") + Decimal("0.2"), Fraction(1, 3) + Fraction(1, 6))
0.30000000000000004 0.3 1/2

copy

copy.copy(obj)
copy.deepcopy(obj)

A deep copy also copies everything nested inside.

Try it
import copy
a = [[1, 2], [3]]
b = copy.deepcopy(a)
b[0].append(99)
print(a, b)
[[1, 2], [3]] [[1, 2, 99], [3]]

string

import string

Handy character constants.

Try it
import string
print(string.ascii_lowercase[:5], string.digits, len(string.punctuation))
abcde 0123456789 32

textwrap

textwrap.wrap(text, width)
textwrap.shorten(text, width)

Wrap or truncate text neatly at word boundaries.

Try it
import textwrap
text = "Python is a language that reads almost like English."
print(textwrap.wrap(text, 20))
print(textwrap.shorten(text, 30))
['Python is a language', 'that reads almost', 'like English.']
Python is a language [...]

itertools / functools

import itertools, functools

See the Iteration section above for the most useful functions.

Try it
import itertools, functools
print(len(list(itertools.permutations(range(4)))), functools.reduce(max, [3, 9, 2]))
24 9

sys

import sys

The interpreter itself: version, recursion limit, exit.

Try it
import sys
print(sys.version_info.major, sys.getrecursionlimit() > 100)
3 True

urllib.parse

urlencode(params)
urlparse(url)

Build and pick apart URLs safely.

Try it
from urllib.parse import urlencode, urlparse
print(urlencode({"q": "python tips", "page": 2}))
u = urlparse("https://api.site.com/users?id=7")
print(u.netloc, u.path, u.query)
q=python+tips&page=2
api.site.com /users id=7

uuid / secrets

uuid.uuid4()
secrets.token_hex(n)

Unique IDs and cryptographically secure random tokens.

Try it
import uuid, secrets
print(len(str(uuid.uuid4())), len(secrets.token_hex(8)))
36 16

time

time.time()
time.sleep(seconds)
time.perf_counter()

Timestamps, pauses and precise timing.

Try it
import time
start = time.perf_counter()
total = sum(range(100_000))
print(total, time.perf_counter() - start >= 0)
4999950000 True
Your next ten minutes

Write Python that does something useful.

Start free. No install, no card, no passive video marathon.

Start learning free → Explore the path