Short answer: Python 3 code is built from a few core pieces: f-strings for formatting, lists, dicts and sets for data, for loops and match for control flow, def and class for structure, pathlib and with open() for files, and try/except for errors. The current stable release is Python 3.14. The tables below show the syntax you will use most, and every example was run on Python 3.14.8.
The examples in this Python cheat sheet were run with Python 3.14.8 on 9 October 2026. Features marked 3.12+ or 3.14 need at least that version; check yours with python3 --version.
Table of Contents
Variables, numbers and f-strings
| Syntax | What it does | Result |
|---|---|---|
port = 443 | Assign. No type declaration; the value carries the type | int |
x, y = y, x | Swap two variables in one line | |
7 / 2 · 7 // 2 · 7 % 2 | True division, floor division, remainder | 3.5 · 3 · 1 |
2 ** 10 | Power | 1024 |
int("42") · float("3.5") · str(10) | Convert between types | 42 · 3.5 · '10' |
bool("") · bool("0") | Empty values are falsy; any non-empty string is truthy | False · True |
f"{name}:{port}" | f-string: insert values | web01:443 |
f"{0.75:.1%}" | Format as a percentage | 75.0% |
f"{1234567:,}" | Thousands separator | 1,234,567 |
f"{port:>6}" | Right-align in 6 characters | ' 443' |
f"{name=}" | Debug form: prints the expression and its value | name='web01' |
isinstance(x, float) | Type check (preferred over type(x) == float) | True/False |
Floats are binary, so round(2.675, 2) gives 2.67, not 2.68. Use the decimal module for money or exact decimal maths.
Strings
| Syntax | What it does |
|---|---|
s.strip() · s.lstrip() · s.rstrip() | Remove surrounding whitespace (or the characters you pass) |
s.lower() · s.upper() | Change case |
s.split(",") · s.split("=", 1) | Split into a list; the second form splits only once |
s.split() | Split on any run of whitespace, ignoring leading and trailing spaces |
"-".join(parts) | Join a list of strings with a separator |
s.replace("old", "new") | Replace every occurrence |
s.startswith("web") · s.endswith(".log") | Prefix and suffix tests (accept a tuple of options) |
"error" in s | Substring test |
s.removesuffix(".txt") | Drop a suffix only if present (3.9+) |
s[0:4] · s[-4:] · s[::-1] | Slice: first four, last four, reversed |
len(s) | Length in characters |
"""...""" | Triple quotes for text that spans several lines |
r"C:\temp\new" | Raw string: backslashes are not escapes (use for regex) |
t"Hello {user}" | Template string (3.14): a Template object, not a str, so a library can escape the values before use |
Lists, tuples, dicts and sets
| Syntax | What it does |
|---|---|
hosts = ["web01", "db01"] | List: ordered, changeable |
hosts.append(x) · hosts.insert(0, x) | Add at the end · at a position |
hosts.remove(x) · hosts.pop() | Remove by value · remove and return the last item |
sorted(hosts, key=len, reverse=True) | New sorted list; hosts.sort() sorts in place |
[h.upper() for h in hosts if h.startswith("web")] | List comprehension with a filter |
point = (10, 20) · a, b = point | Tuple (fixed) and unpacking |
first, *rest = [1, 2, 3, 4] | Star unpacking: rest is [2, 3, 4] |
cfg = {"host": "db01", "port": 3306} | Dict: key-value pairs, insertion order kept |
cfg.get("password", "unset") | Read with a default instead of raising KeyError |
for k, v in cfg.items(): | Loop over keys and values |
cfg | {"port": 3307} | Merge into a new dict; right side wins (3.9+) |
{n: n**2 for n in range(4)} | Dict comprehension |
{1, 2, 3} & {2, 3, 4} · a | b · a - b | Set intersection, union, difference |
Counter(items).most_common(10) | Count occurrences (from collections import Counter) |
defaultdict(list) | Dict that creates missing keys automatically |
enumerate(items, start=1) · zip(a, b) | Index with value · pair two sequences |
Control flow and match
if code < 300:
print("ok")
elif code < 500:
print("client error")
else:
print("server error")
status = "up" if code < 500 else "down" # conditional expression
for i in range(0, 10, 3): # 0 3 6 9
print(i)
while retries < 3:
retries += 1
if (m := re.search(r"\d+", "port 8080")): # walrus: assign inside a test
print(m.group()) # 8080
break leaves a loop, continue skips to the next pass, and a for ... else block runs only when the loop ended without break. Structural pattern matching (3.10+) matches on shape, not just value:
match cmd.split():
case ["restart", service]:
return f"restarting {service}"
case ["status" | "check", *services]:
return f"checking {services}"
case []:
return "empty"
case _:
return "unknown"
Functions, lambdas and type hints
| Syntax | What it does |
|---|---|
def connect(host: str, port: int = 22) -> str: | Function with type hints and a default value |
def f(*args, **kwargs): | Accept any extra positional and keyword arguments |
def f(host, *, timeout=5.0): | Arguments after * must be passed by name |
lambda n: n * n | Anonymous one-expression function |
sorted(hosts, key=len) | Pass a function as an argument |
yield value | Makes the function a generator that produces values lazily |
sum(x for x in range(5)) | Generator expression, no intermediate list |
any(seq) · all(seq) · max(seq) · min(seq) | Common built-ins on iterables |
int | None | Union type hint (3.10+); replaces Optional[int] |
type Port = int | Type alias statement (3.12+) |
def first[T](items: list[T]) -> T: | Generic function syntax (3.12+) |
Type hints are not enforced at run time. Use a checker such as mypy or pyright to catch mistakes. Since 3.14, annotations are evaluated lazily, so a class can refer to itself in hints without quotes.
Classes and dataclasses
class Server:
count = 0 # class attribute
def __init__(self, name: str, ip: str):
self.name = name # instance attributes
self.ip = ip
Server.count += 1
def __repr__(self):
return f"Server({self.name!r}, {self.ip!r})"
@property
def fqdn(self):
return f"{self.name}.example.com"
@classmethod
def from_line(cls, line): # alternative constructor
return cls(*line.split())
class WebServer(Server): # inheritance
def __init__(self, name, ip, vhosts=0):
super().__init__(name, ip)
self.vhosts = vhosts
For classes that mostly hold data, a dataclass writes __init__, __repr__ and __eq__ for you:
from dataclasses import dataclass, field
@dataclass
class Disk:
mount: str
size_gb: int
used_gb: int = 0
tags: list[str] = field(default_factory=list) # never use a bare [] default
d = Disk("/", 80, 13)
print(d) # Disk(mount='/', size_gb=80, used_gb=13, tags=[])
Add @dataclass(frozen=True, slots=True) for an immutable, memory-lean record. Use enum.Enum for a fixed set of named values.
Files, paths and JSON
| Syntax | What it does |
|---|---|
from pathlib import Path | Object-oriented paths; prefer over os.path |
p = Path("/var/log") / "app.log" | Join paths with / |
p.read_text(encoding="utf-8") | Whole file as a string |
p.write_text(data, encoding="utf-8") | Write (overwrites) |
p.exists() · p.stat().st_size | Exists? · Size in bytes |
p.name · p.stem · p.suffix · p.parent | app.log · app · .log · /var/log |
Path("conf").mkdir(parents=True, exist_ok=True) | Create a directory tree |
p.glob("*.conf") · p.rglob("*.log") | Match in one directory · recursively |
p.unlink(missing_ok=True) | Delete a file without error if it is gone |
json.loads(text) · json.dumps(obj, indent=2) | Parse JSON · write JSON |
csv.DictReader(f) | Read CSV rows as dicts keyed by the header |
os.environ.get("HOME") | Environment variable, or None |
with open("/var/log/app.log", encoding="utf-8") as f: # file closes automatically
for line in f: # reads line by line
if "ERROR" in line:
print(line.rstrip())
with open("out.txt", "a", encoding="utf-8") as f: # "w" overwrite, "a" append
f.write("appended\n")
Errors, exceptions and context managers
try:
port = int(value)
except ValueError as e:
print("bad port:", e)
except (KeyError, IndexError):
pass
else:
print("no error") # runs only if nothing was raised
finally:
print("cleanup") # always runs
class ConfigError(Exception):
pass
raise ConfigError("missing port")
raise RuntimeError("calc failed") from e # keep the original cause
Python 3.14 allows except KeyError, IndexError: without brackets, but only when there is no as clause. Keep the brackets if your code must also run on older versions. To ignore one specific error, use with contextlib.suppress(FileNotFoundError): instead of a bare except:, which also swallows Ctrl+C.
For server admins: commands and log parsing
| Syntax | What it does |
|---|---|
subprocess.run(["df", "-h", "/"], capture_output=True, text=True, check=True) | Run a command without a shell; raises CalledProcessError on a non-zero exit |
r.returncode · r.stdout · r.stderr | Exit code and captured output |
shutil.disk_usage("/").free | Free bytes on a filesystem |
shutil.which("mysql") | Full path to a command, or None |
datetime.strptime(s, "%d/%b/%Y:%H:%M:%S %z") | Parse an Apache or Nginx log timestamp |
argparse.ArgumentParser() | Command-line options and --help for your script |
Count requests per IP and per status code in a combined-format access log:
import re
from collections import Counter
pat = re.compile(r'^(\S+) \S+ \S+ \[[^\]]+\] "(\S+) (\S+) [^"]*" (\d{3}) (\d+|-)')
ips, codes = Counter(), Counter()
with open("access.log", encoding="utf-8", errors="replace") as f:
for line in f:
if m := pat.match(line):
ip, method, path, status, size = m.groups()
ips[ip] += 1
codes[status] += 1
print(ips.most_common(10))
print(codes)
Pass commands to subprocess.run as a list. Avoid shell=True with any value that comes from a user, a file or a log line: it allows shell injection. errors="replace" stops one bad byte in a log from crashing the whole script.
Create an isolated environment for each project instead of installing packages system-wide: python3 -m venv .venv, then source .venv/bin/activate and python -m pip install requests. On Debian 12 and later, pip refuses to install into the system Python (PEP 668), and on AlmaLinux, dnf itself runs on the system Python, so leave it alone.
Official documentation (checked 9 October 2026): The Python Tutorial · Built-in Types · What’s new in Python 3.14 · pathlib · re: regular expressions · subprocess
Python Cheat Sheet at a glance


Related: Regex Cheat Sheet: PCRE, JavaScript, Python and grep -E · R Cheat Sheet: Vectors, Data Frames, Strings and Files · JSON Formatter and Validator.
Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.