Python Cheat Sheet
Everyday Python syntax, built-ins and standard library on one page. Targets Python 3.12 and newer; features that need a specific version are marked, e.g. (3.10+).
On this page
Running & Importing #
| Code | What it does |
|---|---|
python3 script.py | Run a script (Windows: py script.py) |
python3 | Start the interactive REPL; quit with exit() (colors and multi-line editing in 3.13+) |
python3 -m http.server | Run a module as a script (here: a web server on port 8000) |
python3 -i script.py | Run a script, then stay in the REPL to inspect its variables |
help(str.split) / dir(obj) | Show the docs / list the attributes of anything |
import math | Import a module, then use math.sqrt(2) |
from pathlib import Path | Import one name directly |
import numpy as np | Import with a shorter alias |
if __name__ == "__main__": | Run code only when the file is executed, not when it is imported |
Install packages in a virtual environment (python3 -m venv .venv, then pip install requests). See the pip & Python venv sheet.
Variables & Types #
| Code | What it does |
|---|---|
x = 5 | Assign (no declaration or type needed) |
a, b = b, a | Swap two variables |
first, *rest = [1, 2, 3] | Unpack with a catch-all: first == 1, rest == [2, 3] |
int / float / complex | Numbers: 5, 3.14, 2+3j |
str / bool / None | Text, True/False, and "no value" |
list / tuple / dict / set | Containers: [1, 2], (1, 2), {"a": 1}, {1, 2} |
isinstance(x, int | float) | Type check, type(x) gives the type (| union 3.10+; older: a tuple (int, float)) |
int("42") / float("3.5") / str(42) | Convert between types |
bool(x) | Falsy values: 0, 0.0, "", [], {}, set(), None; everything else is truthy |
if (n := len(items)) > 3: | Walrus operator: assign inside an expression (3.8+) |
type Point = tuple[float, float] | Type alias statement (3.12+) |
Strings #
| Code | What it does |
|---|---|
f"Hi {name}!" | f-string: put values in text |
f"{price:.2f}" | 2 decimals: 3.50 |
f"{n:,}" | Thousands separator: 1,234,567 |
f"{n:05d}" | Zero-pad to 5 digits: 00042 |
f"{s:>10}" / f"{s:<10}" / f"{s:^10}" | Right / left / center align in 10 characters |
f"{ratio:.1%}" | Percentage: 0.25 becomes 25.0% |
f"{x=}" | Debug output: x=42 |
f"{user["name"]}" | Same quotes inside an f-string (3.12+; older: use the other quote type) |
"""...""" | Multi-line string |
r"C:\new\test" | Raw string: backslashes stay literal (regex, Windows paths) |
s[0] / s[-1] | First / last character |
s[1:4] | Characters 1 to 3 (the end index is excluded) |
s[:3] / s[3:] / s[::-1] | First 3 / from index 3 / reversed |
s.upper() / s.lower() / s.title() | Change case |
s.strip() | Remove whitespace at both ends (lstrip(), rstrip(), or strip(".,")) |
s.split(",") | Split into a list (no argument: split on any whitespace) |
", ".join(words) | Join a list of strings |
s.replace("old", "new") | Replace every occurrence |
s.startswith("http") / s.endswith((".jpg", ".png")) | Prefix / suffix test (accepts a tuple) |
s.find("x") | Index of the first match, -1 if missing (s.index() raises an error) |
"x" in s / s.count("x") | Contains / count occurrences |
s.removeprefix("v") / s.removesuffix(".py") | Remove a prefix / suffix if present (3.9+) |
t"Hi {name}" | Template string: a Template object, not a str, for safe HTML/SQL (3.14+) |
Numbers & Operators #
| Code | What it does |
|---|---|
7 / 2 | 3.5: / always returns a float |
7 // 2 / -7 // 2 | Floor division: 3 / -4 (rounds down) |
7 % 3 / 2 ** 10 | Remainder: 1 / power: 1024 |
round(2.5) / round(3.14159, 2) | 2 (rounds half to even) / 3.14 |
abs(-3) / min(a, b) / max(a, b) | Absolute value, smallest, largest |
x += 1 | Augmented assignment (there is no x++) |
== / != | Equal / not equal (compares values) |
is / is not | Same object (use for None: x is None) |
1 < x < 10 | Chained comparison |
and / or / not | Boolean operators (short-circuit) |
name or "Anonymous" | Fallback when the left side is falsy |
a if cond else b | Conditional expression (ternary) |
math.isclose(0.1 + 0.2, 0.3) | Compare floats (0.1 + 0.2 == 0.3 is False) |
Decimal("0.10") | Exact decimal math for money (from decimal import Decimal) |
Lists & Tuples #
| Code | What it does |
|---|---|
nums = [3, 1, 2] | Create a list (mutable, ordered) |
nums.append(4) / nums.extend([5, 6]) | Add one item / several items to the end |
nums.insert(0, 9) | Insert at an index |
nums.pop() / nums.pop(0) | Remove and return the last item / the item at index 0 |
nums.remove(3) | Remove the first matching value (ValueError if missing) |
del nums[1:3] | Delete by index or slice |
nums.sort() / nums.sort(reverse=True) | Sort in place (returns None) |
sorted(nums) | New sorted list, original unchanged |
words.sort(key=str.lower) | Sort by a key function |
nums[-2:] | Slicing works like on strings (here: last 2 items) |
nums.copy() | Shallow copy (b = nums is the same list, not a copy) |
[0] * 5 / a + b | Repeat / concatenate |
point = (4, 5) / (42,) | Tuple: an immutable list; one item needs a trailing comma |
Dicts & Sets #
| Code | What it does |
|---|---|
d = {"name": "Ann", "age": 30} | Create a dict (keeps insertion order) |
d["name"] / d.get("city", "?") | Get a value (KeyError if missing) / get with a default |
d["city"] = "Ghent" | Add or update a key |
d.setdefault("tags", []) | Return the value, inserting a default first if the key is missing |
d.pop("age") / del d["age"] | Remove a key (pop returns the value) |
d.update(other) / d | other | Merge in place / into a new dict (| 3.9+) |
"name" in d | Key exists? |
for key, value in d.items(): | Loop over pairs (d.keys(), d.values()) |
dict(zip(keys, values)) | Build a dict from two lists |
s = {1, 2, 3} / set() | Create a set (unique items); {} is an empty dict |
s.add(4) / s.discard(4) | Add / remove (discard never raises) |
a | b / a & b / a - b / a ^ b | Union, intersection, difference, in exactly one |
list(dict.fromkeys(items)) | Remove duplicates and keep the order |
Comprehensions #
| Code | What it does |
|---|---|
[x * 2 for x in nums] | List comprehension |
[x for x in nums if x > 0] | With a filter |
[x if x > 0 else 0 for x in nums] | With if/else (goes before for) |
{w: len(w) for w in words} | Dict comprehension |
{w[0] for w in words} | Set comprehension |
sum(x * x for x in nums) | Generator expression: lazy, no list is built |
[(x, y) for x in a for y in b] | Nested loops (outer loop first) |
[[0] * 3 for _ in range(3)] | 3x3 grid ([[0] * 3] * 3 repeats the same row 3 times) |
Control Flow #
| Code | What it does |
|---|---|
if x > 0: / elif x == 0: / else: | Conditions (indentation defines the block) |
for item in items: | Loop over any iterable |
for i in range(2, 10, 2): | 2, 4, 6, 8 (range(5) is 0 to 4) |
while attempts < 3: | Loop while a condition is true |
break / continue | Leave the loop / skip to the next iteration |
for ... else: | The else block runs only if the loop did not break |
pass | Do nothing (placeholder for an empty block) |
Structural pattern matching (3.10+):
match event:
case {"type": "click", "pos": (x, y)}: # dict with a 2-item sequence
print(f"Click at {x}, {y}")
case {"type": "key", "key": "q" | "Q"}: # alternatives
quit()
case [first, *rest]: # any list
print(first, rest)
case str() as text if text: # type + guard
print(text)
case _: # default
print("Unknown event")
Functions #
| Code | What it does |
|---|---|
def greet(name="World"): | Define a function with a default value |
greet(name="Ann") | Call with a keyword argument |
def total(*args): | Any number of positional arguments (a tuple) |
def config(**kwargs): | Any number of keyword arguments (a dict) |
def save(data, *, overwrite=False): | Arguments after * are keyword-only |
def div(a, b, /): | Arguments before / are positional-only |
f(*items, **options) | Unpack a list / dict into arguments |
lambda x: x * 2 | Small anonymous function |
def add(a: int, b: int = 0) -> int: | Type hints (for editors and checkers like mypy, not enforced at runtime) |
str | None | "str or None" in hints (3.10+; older: Optional[str]) |
def first[T](items: list[T]) -> T: | Generic function (3.12+; older: TypeVar) |
yield value | Makes the function a generator (produces values lazily) |
@functools.cache | Decorator: remember results of earlier calls |
Classes #
from dataclasses import dataclass, field
@dataclass
class Product:
name: str
price: float
tags: list[str] = field(default_factory=list) # never use a bare [] default
@property
def price_incl_vat(self) -> float: # read as p.price_incl_vat
return round(self.price * 1.21, 2)
p = Product("Sourdough", 4.0) # Product(name='Sourdough', price=4.0, tags=[])
p.price_incl_vat # 4.84
| Code | What it does |
|---|---|
def __init__(self, name): | Constructor of a regular class (self.name = name) |
class Bread(Product): | Inheritance; call the parent with super().__init__(...) |
__repr__ / __str__ | Text for developers (repr(), REPL) / for users (print, str()) |
__eq__ / __lt__ | Define == / < (< makes objects sortable) |
__len__ / __getitem__ / __iter__ | Support len(obj), obj[key], for x in obj |
__enter__ / __exit__ | Support with obj: |
@classmethod / @staticmethod | Method that gets the class cls / plain function inside the class |
@dataclass(frozen=True, slots=True) | Immutable dataclass with less memory (slots 3.10+) |
Exceptions #
try:
value = int(text)
except ValueError as e:
print(f"Not a number: {e}")
except (TypeError, KeyError):
value = 0
else:
print("Runs only if nothing was raised")
finally:
print("Always runs (cleanup)")
| Code | What it does |
|---|---|
raise ValueError("Age must be positive") | Raise an exception |
raise | Re-raise the current exception (inside except) |
raise AppError("Load failed") from e | Raise a new error and keep the original as its cause |
class AppError(Exception): pass | Custom exception (inherit from Exception) |
except Exception as e: | Catch almost everything (avoid a bare except:) |
except ValueError, TypeError: | Several types without parentheses (3.14+, only without as) |
except* ValueError: | Handle part of an ExceptionGroup (3.11+) |
e.add_note("while reading config") | Add context shown in the traceback (3.11+) |
with suppress(FileNotFoundError): | Ignore one error type (from contextlib import suppress) |
Files & pathlib #
with open("data.txt", encoding="utf-8") as f: # file is closed automatically
for line in f:
print(line.rstrip())
with open("log.txt", "a", encoding="utf-8") as f: # "w" overwrite, "a" append, "rb" binary
f.write("Done\n")
| Code | What it does |
|---|---|
Path("data") / "file.txt" | Build a path that works on every OS (from pathlib import Path) |
Path.cwd() / Path.home() | Current folder / home folder |
p.read_text(encoding="utf-8") | Read a whole text file |
p.write_text(text, encoding="utf-8") | Write a whole text file (overwrites) |
p.exists() / p.is_file() / p.is_dir() | Checks |
p.name / p.stem / p.suffix / p.parent | report.pdf / report / .pdf / the folder |
p.mkdir(parents=True, exist_ok=True) | Create a folder and its parents |
p.glob("*.csv") / p.rglob("*.py") | Find files / also in subfolders |
p.unlink(missing_ok=True) / p.rename(target) | Delete / move or rename a file |
Built-ins & Standard Library #
| Code | What it does |
|---|---|
enumerate(items, start=1) | Pairs of (index, item) for loops |
zip(names, scores, strict=True) | Pair up items; strict raises if lengths differ (3.10+) |
sorted(people, key=lambda p: p.age) | Sort by a key (add reverse=True for descending) |
any(x < 0 for x in nums) / all(...) | At least one / every item is truthy |
min(words, key=len, default=None) | Smallest by a key, default for an empty input |
sum(nums) / reversed(nums) | Total / iterate backwards |
map(int, parts) / filter(None, items) | Apply a function / drop falsy items (lazy) |
input("Name? ") | Read a line from the user (always a str) |
json.loads(text) / json.dumps(obj, indent=2) | Parse / write JSON (see the JSON sheet) |
datetime.now(UTC) | Current time with time zone (from datetime import datetime, UTC, 3.11+) |
datetime.fromisoformat("2026-10-11") / dt.strftime("%d/%m/%Y") | Parse / format a date |
dt + timedelta(days=7) | Date arithmetic |
Counter(words).most_common(3) | Count things (from collections import ...) |
defaultdict(list) / deque(maxlen=10) | Dict with automatic defaults / fast queue |
chain(a, b) / batched(items, 3) | Iterate as one / chunks of 3 (itertools; batched 3.12+) |
re.findall(r"\d+", s) / re.sub(r"\s+", " ", s) | Find all matches / replace (see the Regex sheet) |
sys.argv / os.environ.get("HOME") | Command-line arguments / environment variable |
Tips #
- Never use a mutable default like
def f(items=[]): the list is shared between calls. Useitems=Noneand create it inside. list.sort()returnsNone, sonums = nums.sort()loses your list. Usesorted(nums)for a new one.- Always pass
encoding="utf-8"toopen()andread_text(); otherwise the encoding can differ between Windows and Linux. - Use
is None/is not None, not== None. - Catch the specific exception you expect. A bare
except:even swallowsCtrl + C(KeyboardInterrupt) and hides real bugs. - Format your code with
ruff formatorblackand follow PEP 8: 4-space indents,snake_casenames,PascalCaseclasses.
Nothing on this sheet matches “”.