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.
- Look up syntax quickly without leaving the course
- Pick the idiomatic built-in or stdlib tool for a common job
- Jump to the module that explains each topic in depth
Built-in types and operators
| Type | Literal | Mutable? | Notes |
|---|---|---|---|
int | 42, 0xFF, 0b1010, 1_000_000 | No | Arbitrary precision |
float | 3.14, 1e-9, float("inf") | No | IEEE-754 double; 0.1 + 0.2 != 0.3 |
complex | 2 + 3j | No | .real, .imag |
bool | True, False | No | Subclass of int |
NoneType | None | No | Test with is None |
str | "hi", 'hi', """multi""", r"\d" | No | Unicode text |
bytes / bytearray | b"\x00" | No / Yes | Raw binary data |
list | [1, 2] | Yes | Ordered sequence |
tuple | (1, 2), 1, | No | Fixed record |
dict | {"a": 1} | Yes | Insertion-ordered mapping |
set / frozenset | {1, 2}, set() | Yes / No | {} is an empty dict |
range | range(0, 10, 2) | No | Lazy 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) # 6name, 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.12from 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_specord("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 encodingDepth: 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).xd = {"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 keyss = {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) # hashablefrom 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 lookupDepth: 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__ truthinessExceptions
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
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
| Job | Reach for | One-liner |
|---|---|---|
| Paths and files | pathlib | Path("data").glob("*.csv"), p.read_text(encoding="utf-8"), p.copy(dst) (3.14) |
| JSON | json | json.loads(s), json.dumps(obj, indent=2) |
| CSV | csv | csv.DictReader(f), csv.DictWriter(f, fieldnames) |
| TOML (read) | tomllib | tomllib.load(open("pixi.toml", "rb")) |
| Dates and times | datetime, zoneinfo | datetime.now(ZoneInfo("Europe/Oslo")), date.fromisoformat("2026-10-14") |
| Regular expressions | re | re.findall(r"\d+", s), re.sub(r"\s+", " ", s) |
| Math and stats | math, statistics, random, decimal, fractions | math.isclose(a, b), statistics.median(xs) |
| Heaps and binary search | heapq, bisect | heapq.nlargest(3, xs), heapq.heappop_max(h) (3.14), bisect.insort(xs, x) |
| IDs and secrets | uuid, secrets, hashlib | uuid.uuid7() (3.14), secrets.token_urlsafe(16), hashlib.sha256(b).hexdigest() |
| CLI arguments | argparse | ArgumentParser(suggest_on_error=True) |
| Compression | compression.zstd (3.14), gzip, zipfile, tarfile | zstd.compress(data) |
| Databases | sqlite3 | with sqlite3.connect("app.db") as con: con.execute(sql, params) |
| Processes | subprocess | subprocess.run(["git", "status"], check=True, capture_output=True, text=True) |
| Concurrency | concurrent.futures | ThreadPoolExecutor, ProcessPoolExecutor, InterpreterPoolExecutor (3.14) |
| Timing and profiling | time, timeit, cProfile | time.perf_counter(), pixi run python -m cProfile -s cumtime app.py |
| Copying | copy | copy.copy(x), copy.deepcopy(x) |
| Logging (professional code) | structlog (via Pixi) | log = structlog.get_logger(); log.info("loaded", rows=n) |
Check yourself
Going further
- The Python Tutorial and Built-in Functions
- Format specification mini-language
- Glossary for any term on this page