Reference · Language

Python Cheat Sheet

The syntax and built-ins you reach for every day, grouped by topic, for Python 3.14. Every code block has a Copy button; tabs show alternatives side by side; a few cells let you try things right here.

⏱ Keep open while you work3.14 baselineFull docs: Python standard library

Built-in types and operators

TypeLiteralMutable?Notes
int42, 0xFF, 0b1010, 1_000_000NoArbitrary precision
float3.14, 1e-9, float("inf")NoIEEE-754 double; 0.1 + 0.2 != 0.3
complex2 + 3jNo.real, .imag
boolTrue, FalseNoSubclass of int
NoneTypeNoneNoTest with is None
str"hi", 'hi', """multi""", r"\d"NoUnicode text
bytes / bytearrayb"\x00"No / YesRaw binary data
list[1, 2]YesOrdered sequence
tuple(1, 2), 1,NoFixed record
dict{"a": 1}YesInsertion-ordered mapping
set / frozenset{1, 2}, set()Yes / No{} is an empty dict
rangerange(0, 10, 2)NoLazy arithmetic sequence
7 / 2    # 3.5   true division
7 // 2   # 3     floor division (-7 // 2 == -4)
7 % 2    # 1     remainder (sign follows the divisor)
2 ** 10  # 1024
divmod(7, 2)          # (3, 1)
abs(-3), round(2.675, 2), round(2.5)   # 3, 2.67, 2 (banker's rounding)
x == y   # equal values      x is y   # same object
a < b < c             # chained comparison
x if cond else y      # conditional expression
a and b, a or b, not a   # short-circuit; return an operand, not always a bool
if (n := len(items)) > 10: ...   # walrus: assign inside an expression
int("42"), float("1.5"), str(3), bool(""), list("abc")  # conversions
isinstance(x, (int, float))   # type check (prefer over type(x) == int)

Falsy values: False, None, 0, 0.0, "", [], (), {}, set(), range(0). Everything else is truthy. More in M02.

Strings, f-strings, and t-strings

s = "  Hello, World  "
s.strip(), s.lstrip(), s.rstrip()      # trim whitespace
s.lower(), s.upper(), s.title(), s.casefold()
s.split(","), "a b  c".split()          # ['  Hello', ' World  '], ['a', 'b', 'c']
", ".join(["a", "b"])                   # 'a, b'
s.replace("World", "Py")
s.startswith("  H"), s.endswith("  ")
s.find("o"), s.index("o"), s.count("l") # find returns -1 if missing; index raises
"42".isdigit(), "abc".isalpha(), " ".isspace()
"py".center(8, "*"), "7".zfill(3)       # '***py***', '007'
"report.csv".removesuffix(".csv")       # 'report'
s.partition(",")                        # ('  Hello', ',', ' World  ')
s = "python"
s[0], s[-1]       # 'p', 'n'
s[1:4]            # 'yth'   start inclusive, stop exclusive
s[:2], s[2:]      # 'py', 'thon'
s[::2]            # 'pto'
s[::-1]           # 'nohtyp'  reversed
len(s)            # 6
name, n, pi = "Ada", 1234567, 3.14159
f"{name!r}"         # "'Ada'"     repr
f"{n:,}"            # '1,234,567'
f"{n:_}"            # '1_234_567'
f"{pi:.2f}"         # '3.14'
f"{0.256:.1%}"      # '25.6%'
f"{name:>8}"        # '     Ada'   right align (< left, ^ center)
f"{name:*^9}"       # '***Ada***'
f"{255:#x} {5:08b}" # '0xff 00000101'
f"{n = }"           # 'n = 1234567'  self-documenting
f"{'nested' + "quotes"}"   # same quotes allowed inside since 3.12
from string.templatelib import Template, Interpolation

user = "<b>Ada</b>"
tpl: Template = t"Hello {user}!"
tpl.strings          # ('Hello ', '!')
tpl.values           # ('<b>Ada</b>',)
for part in tpl:     # str and Interpolation, in order
    if isinstance(part, Interpolation):
        part.value, part.expression, part.conversion, part.format_spec
ord("A"), chr(65)              # 65, 'A'
"café".encode("utf-8")         # b'caf\xc3\xa9'
b"caf\xc3\xa9".decode("utf-8") # 'café'
len("café"), len("café".encode())   # 4, 5
open("f.txt", encoding="utf-8")     # always say the encoding

Depth: M03 Strings & Text. Template strings: What's New in 3.14.

Collections

xs = [3, 1, 2]
xs.append(4); xs.extend([5, 6]); xs.insert(0, 0)
xs.pop(), xs.pop(0), xs.remove(3)    # by end, by index, by value
xs.index(2), xs.count(2), 2 in xs
xs.sort(); xs.sort(key=abs, reverse=True)   # in place, returns None
sorted(xs), reversed(xs), min(xs), max(xs), sum(xs)
xs[1:3] = [9, 9]       # slice assignment
xs.copy(), xs[:]       # shallow copies
del xs[0]
point = (3, 4)
x, y = point
first, *rest = [1, 2, 3, 4]      # 1, [2, 3, 4]
a, b = b, a                      # swap
(x, y), z = (1, 2), 3            # nested
for i, item in enumerate(items, start=1): ...
for a, b in zip(xs, ys, strict=True): ...
from collections import namedtuple
P = namedtuple("P", "x y"); P(1, 2).x
d = {"a": 1, "b": 2}
d["c"] = 3; d.get("z", 0); d.setdefault("k", [])
d.pop("a"), d.popitem()          # popitem removes the last inserted
d.keys(), d.values(), d.items()
for key, value in d.items(): ...
d | {"x": 9}; d |= {"y": 8}      # merge (new / in place)
dict.fromkeys("abc", 0)          # {'a': 0, 'b': 0, 'c': 0}
{**d1, **d2}                     # merge, d2 wins
"a" in d                         # checks keys
s = {1, 2, 3}
s.add(4); s.discard(9); s.remove(1)   # remove raises if missing
a | b, a & b, a - b, a ^ b             # union, intersection, difference, symmetric
a <= b, a.isdisjoint(b)
frozenset(s)                          # hashable
from collections import Counter, defaultdict, deque, OrderedDict, ChainMap
Counter("banana").most_common(2)    # [('a', 3), ('n', 2)]
groups = defaultdict(list); groups["k"].append(1)
q = deque(maxlen=3); q.append(1); q.appendleft(0); q.popleft(); q.rotate(1)
ChainMap(cli_args, env, defaults)["key"]   # layered lookup

Depth: M06 Collections; costs in the Complexity cheat sheet.

Comprehensions and generator expressions

[x * x for x in range(5)]                    # list
[x for x in nums if x % 2 == 0]              # filter
["even" if x % 2 == 0 else "odd" for x in nums]  # map with a condition
{w: len(w) for w in words}                   # dict
{c.lower() for c in text if c.isalpha()}     # set
(x * x for x in range(10**9))                # generator: lazy, O(1) memory
sum(x * x for x in nums)                     # no extra brackets needed
[(r, c) for r in range(3) for c in range(3) if r != c]   # nested: outer loop first
[x for row in matrix for x in row]           # flatten one level

Control flow

if x > 0:
    ...
elif x == 0:
    ...
else:
    ...

while n > 0:
    n -= 1
    if n == 3:
        continue
    if n == 1:
        break
else:
    ...   # runs only if no break
for i in range(10):            # 0..9
for i in range(10, 0, -2):     # 10, 8, 6, 4, 2
for i, x in enumerate(xs):
for a, b in zip(xs, ys):
for k, v in d.items():
for x in reversed(xs):
for x in sorted(xs, key=len):

for item in items:
    if is_match(item):
        break
else:
    item = None   # loop finished without break

Depth: M04 Control Flow.

Structural pattern matching

match command.split():
    case ["go", direction]:                     # sequence with capture
        move(direction)
    case ["drop", *objects]:                    # star capture
        drop(objects)
    case ["quit" | "exit"]:                     # alternatives
        quit()
    case _:                                     # wildcard
        print("unknown")

match event:
    case {"type": "click", "pos": (x, y)}:      # mapping + nested sequence
        ...
    case Point(x=0, y=0):                       # class pattern
        ...
    case Point(x=x, y=y) if x == y:             # guard
        ...
    case int() | float() as number:             # type check + bind
        ...
    case Color.RED:                             # dotted name = value pattern
        ...

Functions

def greet(name: str, greeting: str = "Hello") -> str:
    """Return a greeting."""
    return f"{greeting}, {name}!"

def f(pos_only, /, normal, *args, kw_only, **kwargs): ...
f(1, 2, 3, 4, kw_only=5, extra=6)   # args=(3, 4), kwargs={'extra': 6}
f(*[1, 2], **{"kw_only": 3})       # unpack into a call

square = lambda x: x * x             # small anonymous function
sorted(people, key=lambda p: (p.age, p.name))

def outer():
    count = 0
    def inc():
        nonlocal count             # rebind the enclosing variable
        count += 1
        return count
    return inc                     # a closure

def bad(items=[]): ...             # mutable default: shared between calls!
def good(items=None):
    items = [] if items is None else items
import functools

@functools.cache                      # memoize
def fib(n: int) -> int:
    return n if n < 2 else fib(n - 1) + fib(n - 2)

def timed(func):                      # a decorator
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

Scope rule: LEGB (Local, Enclosing, Global, Built-in). Depth: M05 Functions, M15 Decorators, M18 Functional Python.

Classes and dataclasses

class Account:
    interest = 0.02                      # class attribute (shared)

    def __init__(self, owner: str, balance: float = 0) -> None:
        self.owner = owner                # instance attribute
        self._balance = balance           # "private" by convention

    @property
    def balance(self) -> float:           # read like an attribute
        return self._balance

    def deposit(self, amount: float) -> None:
        if amount <= 0:
            raise ValueError("amount must be positive")
        self._balance += amount

    @classmethod
    def empty(cls, owner: str) -> "Account":   # alternative constructor
        return cls(owner)

    @staticmethod
    def fee(amount: float) -> float:
        return amount * 0.01

    def __repr__(self) -> str:
        return f"Account({self.owner!r}, {self._balance})"

class Savings(Account):
    def __init__(self, owner: str) -> None:
        super().__init__(owner)
from dataclasses import dataclass, field

@dataclass(frozen=True, slots=True, kw_only=True)
class Item:
    name: str
    price: float
    tags: list[str] = field(default_factory=list)   # never a bare [] default

    def __post_init__(self) -> None:
        if self.price < 0:
            raise ValueError("price must be >= 0")

item = Item(name="pen", price=1.5)
# free: __init__, __repr__, __eq__, and (frozen) __hash__
from dataclasses import replace, asdict
replace(item, price=2.0), asdict(item)
from enum import Enum, StrEnum, auto
class Color(Enum):
    RED = auto()
    GREEN = auto()
class Level(StrEnum):
    DEBUG = auto()      # value 'debug'

from typing import NamedTuple, TypedDict
class Pair(NamedTuple):
    left: int
    right: int
class Movie(TypedDict):
    title: str
    year: int
__repr__ / __str__        repr(x) / str(x)
__eq__ / __hash__         x == y / hash(x)  (define both, or neither)
__lt__ (+ functools.total_ordering)   sorting
__len__ / __getitem__ / __contains__ / __iter__   containers
__add__ / __radd__ / __iadd__        + / reflected + / +=
__call__                  x()
__enter__ / __exit__      with x:
__bool__                  truthiness

Depth: M10, M11, M12, M13.

Exceptions

try:
    value = int(text)
except ValueError as exc:            # one type, bound to a name
    log_bad_input(exc)
except KeyError, IndexError:         # 3.14: several types, no parentheses (no 'as')
    ...
except (TypeError, OverflowError) as exc:   # with 'as', parentheses are required
    ...
else:
    use(value)                       # only if no exception
finally:
    cleanup()                        # always (no return/break/continue here: 3.14 warns)

raise ValueError(f"bad value: {value!r}")
raise ConfigError("cannot load") from exc   # chain: shows the cause

class ConfigError(Exception):
    """Raised when configuration is invalid."""

try:
    async_work()
except* TimeoutError as group:       # exception groups (TaskGroup errors)
    ...
exc.add_note("while loading settings.toml")

Common built-ins: ValueError, TypeError, KeyError, IndexError, AttributeError, FileNotFoundError, ZeroDivisionError, StopIteration, NotImplementedError. Depth: M07 Errors & Exceptions.

Iterators and generators

it = iter([1, 2, 3]); next(it); next(it, "default")

def countdown(n):                 # generator function
    while n > 0:
        yield n
        n -= 1

def chain_all(*iterables):
    for iterable in iterables:
        yield from iterable       # delegate

import itertools as it
it.count(10), it.cycle("ab"), it.repeat(0, 3)
it.chain([1], [2]), it.islice(gen, 5), it.batched(range(7), 3)
it.groupby(sorted(rows, key=key), key=key)    # sort first!
it.accumulate([1, 2, 3]), it.pairwise("abc")
it.product("ab", repeat=2), it.permutations("abc", 2), it.combinations("abc", 2)
it.takewhile(pred, xs), it.dropwhile(pred, xs), it.zip_longest(a, b, fillvalue=0)
map(f, xs, ys, strict=True)       # 3.14: strict length check
any(x > 0 for x in xs), all(...)

Depth: M14 Iterators & Generators.

Context managers

with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
    dst.write(src.read())

from contextlib import contextmanager, suppress, ExitStack, redirect_stdout, chdir

@contextmanager
def timer(label):
    start = time.perf_counter()
    try:
        yield
    finally:
        print(label, time.perf_counter() - start)

with suppress(FileNotFoundError):      # deliberate, documented ignore
    os.remove("tmp.txt")

with ExitStack() as stack:             # a dynamic number of resources
    files = [stack.enter_context(open(p, encoding="utf-8")) for p in paths]

class Managed:
    def __enter__(self): return self
    def __exit__(self, exc_type, exc, tb): return False   # False: don't swallow errors

Depth: M15 Decorators & Context Managers.

Type hints

def mean(values: list[float]) -> float: ...
def find(name: str) -> User | None: ...           # optional
def merge(a: dict[str, int], b: dict[str, int]) -> dict[str, int]: ...
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
def apply(f: Callable[[int], str], xs: Iterable[int]) -> list[str]: ...

def first[T](items: Sequence[T]) -> T: ...       # PEP 695 generics
class Box[T]:
    def __init__(self, item: T) -> None: self.item = item
type Vector = list[float]                         # type alias

from typing import Protocol, Literal, Final, TypedDict, Self, Any, overload
class SupportsClose(Protocol):
    def close(self) -> None: ...
Mode = Literal["r", "w"]
MAX: Final = 10

class Node:                                        # 3.14: forward refs without quotes
    def add(self, child: Node) -> Node: ...

from annotationlib import get_annotations, Format
get_annotations(Node.add, format=Format.STRING)
pixi run mypy --strict src/

Depth: M16 Type Hints & Static Typing.

Async

import asyncio

async def fetch(name: str, delay: float) -> str:
    await asyncio.sleep(delay)              # yield to the event loop
    return name

async def main() -> None:
    a, b = await asyncio.gather(fetch("a", 1), fetch("b", 1))   # ~1 s total

    async with asyncio.TaskGroup() as tg:   # structured concurrency
        t1 = tg.create_task(fetch("x", 0.5))
        t2 = tg.create_task(fetch("y", 0.2))
    print(t1.result(), t2.result())

    async with asyncio.timeout(2):          # cancel if too slow
        await fetch("slow", 1)

    sem = asyncio.Semaphore(10)             # limit concurrency
    async with sem: ...

asyncio.run(main())                         # in a script (top-level await in the browser)

Depth: M38 Async Programming.

Common standard library

JobReach forOne-liner
Paths and filespathlibPath("data").glob("*.csv"), p.read_text(encoding="utf-8"), p.copy(dst) (3.14)
JSONjsonjson.loads(s), json.dumps(obj, indent=2)
CSVcsvcsv.DictReader(f), csv.DictWriter(f, fieldnames)
TOML (read)tomllibtomllib.load(open("pixi.toml", "rb"))
Dates and timesdatetime, zoneinfodatetime.now(ZoneInfo("Europe/Oslo")), date.fromisoformat("2026-10-14")
Regular expressionsrere.findall(r"\d+", s), re.sub(r"\s+", " ", s)
Math and statsmath, statistics, random, decimal, fractionsmath.isclose(a, b), statistics.median(xs)
Heaps and binary searchheapq, bisectheapq.nlargest(3, xs), heapq.heappop_max(h) (3.14), bisect.insort(xs, x)
IDs and secretsuuid, secrets, hashlibuuid.uuid7() (3.14), secrets.token_urlsafe(16), hashlib.sha256(b).hexdigest()
CLI argumentsargparseArgumentParser(suggest_on_error=True)
Compressioncompression.zstd (3.14), gzip, zipfile, tarfilezstd.compress(data)
Databasessqlite3with sqlite3.connect("app.db") as con: con.execute(sql, params)
Processessubprocesssubprocess.run(["git", "status"], check=True, capture_output=True, text=True)
Concurrencyconcurrent.futuresThreadPoolExecutor, ProcessPoolExecutor, InterpreterPoolExecutor (3.14)
Timing and profilingtime, timeit, cProfiletime.perf_counter(), pixi run python -m cProfile -s cumtime app.py
Copyingcopycopy.copy(x), copy.deepcopy(x)
Logging (professional code)structlog (via Pixi)log = structlog.get_logger(); log.info("loaded", rows=n)

Depth: M09 Files, M40 Standard Library Power Tools.

Check yourself

Going further