# Python Cheat Sheet: Syntax, Data Types and File Handling

Source: https://srvscripts.com/guides/python-cheat-sheet/
Updated: 2026-10-09
Publisher: srvScripts (https://srvscripts.com/)

**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`.

## 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](https://docs.python.org/3/tutorial/index.html) · [Built-in Types](https://docs.python.org/3/library/stdtypes.html) · [What’s new in Python 3.14](https://docs.python.org/3/whatsnew/3.14.html) · [pathlib](https://docs.python.org/3/library/pathlib.html) · [re: regular expressions](https://docs.python.org/3/library/re.html) · [subprocess](https://docs.python.org/3/library/subprocess.html)

## Python Cheat Sheet at a glance

In short: A compact Python 3.14 reference covering syntax, data types, files, errors and log parsing, with every example run on Python 3.14.8.

Python Cheat Sheet: what this guide covers.

**Related:** [Regex Cheat Sheet: PCRE, JavaScript, Python and grep -E](https://srvscripts.com/guides/regex-cheat-sheet/) · [R Cheat Sheet: Vectors, Data Frames, Strings and Files](https://srvscripts.com/guides/r-cheat-sheet/) · [JSON Formatter and Validator](https://srvscripts.com/tools/json-formatter/).
