Part 4 · 1 chapters · ~8 min

Idioms

Writing Pythonic code: EAFP versus LBYL, iteration protocols, comprehensions and generator expressions, unpacking, enumerate and zip, context managers, dataclasses, pathlib, f-strings, the standard library before dependencies, and the Zen of Python in practice.

8

Pythonic code

code
# EAFP: easier to ask forgiveness than permission
try: acct = accounts[account_id]
except KeyError: raise AccountNotFound(account_id) from None

# iterate directly; enumerate and zip instead of indices
for i, (t, fee) in enumerate(zip(transfers, fees), start=1): print(f"{i}. {t.id} fee {fee}")

# unpacking and the walrus operator
first, *rest = sorted(transfers, key=lambda t: t.created_at)
if (n := len(rest)) > 100: log.warning("%d transfers pending", n)

from pathlib import Path
for p in Path("statements").glob("2026-09-*.csv"): process(p.read_text(encoding="utf-8"))

from collections import Counter, defaultdict
by_status = Counter(t.status for t in transfers)          # {'completed': 812, 'pending': 41}
by_owner = defaultdict(list)
for t in transfers: by_owner[t.owner].append(t)
Pythonicinstead of
if not items:if len(items) == 0:
with open(...) as f:manual open/close
dataclass or NamedTupledicts with fixed keys everywhere
any(), all(), sum() with generatorsaccumulating loops
small modules with clear namesutils.py holding everything