Python Basics

Core Python syntax, variables, type annotations, and control flow.

Variables and Type Annotations

Type-annotated variable — annotation is documentation, not enforcement (use mypy for that)
name: str = "Evan"
Union type with None — Python 3.10+ syntax, replaces Optional[int]
x: int | None = None

F-strings and Formatting

f-string with format spec — :, adds thousands separator, :>10 right-aligns, :.2f for floats
f"Host {hostname} has {count:,} sessions"
# "Host ise-01 has 14,302 sessions"
f-string format codes — 2 decimal places, percentage with 1 decimal, zero-padded hex
f"{price:.2f}"      # "19.99"
f"{ratio:.1%}"      # "85.3%"
f"{num:#010x}"      # "0x0000ff"

Collections Basics

List basics — mutable, ordered, append adds one, extend adds iterable, += is extend
items = [1, 2, 3]
items.append(4)        # [1, 2, 3, 4]
items.extend([5, 6])   # [1, 2, 3, 4, 5, 6]
Star unpacking — first=1, rest=[2,3,4,5], works anywhere: first, *mid, last = seq
first, *rest = [1, 2, 3, 4, 5]
# first = 1, rest = [2, 3, 4, 5]
Tuple swap — no temp variable needed, Python evaluates right side fully before assignment
a, b = b, a

Comprehensions

List comprehension with filter — builds [0, 4, 16, 36, 64], replaces map+filter
squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
Dict comprehension with filter — build dicts inline, drop None values
clean = {k: v for k, v in pairs if v is not None}
Set comprehension — deduplicate and transform in one expression
unique = {x.lower() for x in names}
Generator expression — lazy evaluation, constant memory, iterate once only
total = sum(x**2 for x in range(1_000_000))

Slicing and Indexing

Slice tricks — every 2nd element, reversed, odd-indexed elements (step argument)
seq[::2]    # every 2nd element
seq[::-1]   # reversed
seq[1::2]   # odd-indexed elements
Negative indexing — last 3 elements, everything except last
seq[-3:]    # last 3 elements
seq[:-1]    # everything except last

Truthiness and Conditionals

Truthiness — empty containers, 0, None, "" are falsy; everything else is truthy
bool([])   # False
bool([0])  # True -- non-empty list, even if contents are falsy
Ternary expression — inline conditional, reads left to right
result = value if value is not None else default
Walrus operator := — assign and test in one expression, avoids double evaluation
if (n := len(items)) > 10:
    print(f"{n} items")
Short-circuit default — or returns first truthy value, handles both None and empty string
x = data.get("key") or "fallback"

Type Checking and Data Structures

isinstance with tuple — multiple type checks, preferred over type(obj) == str
isinstance(obj, (str, int, float))
Dataclass — auto-generates init, repr, eq from type annotations
from dataclasses import dataclass

@dataclass
class Device:
    hostname: str
    ip: str
    port: int = 443
Enum — prevents magic strings, Status.ACTIVE.value gives "active"
from enum import Enum

class Status(Enum):
    ACTIVE = "active"
    DISABLED = "disabled"

Error Handling and Resources

Multi-exception catch — tuple of exception types, bind to variable for inspection
try:
    result = api_call()
except (KeyError, ValueError) as e:
    logger.error(f"Bad data: {e}")
Context manager — guarantees file close even on exception, use for any resource
with open("file.txt") as f:
    data = f.read()

Standard Library Essentials

Pathlib — object-oriented filesystem ops, replaces os.path, supports / operator for joining
from pathlib import Path

config = Path("/etc/hosts").read_text()
log_dir = Path.home() / "logs" / "today"
JSON parsing — loads from string, load from file, dumps to string with indent=2
import json

data = json.loads(response.text)
print(json.dumps(data, indent=2))
Counter — frequency counting in one line, .most_common(n) returns top n as sorted tuples
from collections import Counter

word_freq = Counter(words).most_common(10)
Strict zip — Python 3.10+, raises ValueError if iterables have different lengths
for name, score in zip(names, scores, strict=True):
    print(f"{name}: {score}")