Python #
Core syntax, data structures, and the idioms worth knowing.
Data structures #
xs = [1, 2, 3] # list (mutable, ordered)
t = (1, 2) # tuple (immutable)
s = {1, 2, 3} # set (unique)
d = {"id": 1, "ok": True} # dict
xs[0], xs[-1], xs[1:3] # index / negative / slice
d.get("missing", 0) # safe lookup with default
Strings & f-strings #
name = "turtle"
f"hi {name!r}, {3.14159:.2f}" # repr + format spec -> hi 'turtle', 3.14
"a,b,c".split(",") # -> ['a', 'b', 'c']
" ".join(["a", "b"]) # -> 'a b'
text.strip().lower() # chainable
f"{name=}" # self-documenting -> name='turtle' (3.8+)
Flow & comprehensions #
[x*x for x in range(5) if x % 2 == 0] # list comp -> [0, 4, 16]
{k: v for k, v in pairs} # dict comp
(x for x in xs) # generator (lazy)
for i, v in enumerate(xs): ...
for a, b in zip(xs, ys): ...
value = a if cond else b # ternary
Functions #
def greet(name, *args, greeting="hi", **kwargs):
return f"{greeting} {name}"
add = lambda a, b: a + b
def square(x: int) -> int: # type hints
return x * x
Classes & dataclasses #
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int = 0
def dist(self) -> float:
return (self.x**2 + self.y**2) ** 0.5
Point(3, 4).dist() # -> 5.0
Context managers & errors #
with open("data.txt") as f: # file auto-closes
for line in f:
process(line)
try:
risky()
except (ValueError, KeyError) as e:
log(e)
finally:
cleanup()
Stdlib worth knowing #
from collections import Counter, defaultdict
from itertools import chain, groupby
from pathlib import Path
Path("a/b.txt").read_text()
import json; json.dumps(obj, indent=2)
Pattern matching & walrus #
match command.split():
case ["go", direction]: move(direction)
case ["drop", *items]: drop(items) # capture the rest
case _: unknown() # default (3.10+)
if (n := len(xs)) > 10: # walrus: assign and test at once
print(f"too long ({n})")
Modern type hints #
def parse(raw: str) -> list[int]: # built-in generics (3.9+)
return [int(x) for x in raw.split()]
def find(key: str) -> int | None: # union / optional (3.10+)
return cache.get(key)
from typing import TypedDict, Literal # structured + enumerated types
Unpacking & merging #
first, *rest = [1, 2, 3, 4] # first=1, rest=[2, 3, 4]
a, b = b, a # swap without a temp
merged = {**base, **extra} # combine dicts
settings = base | extra # dict union operator (3.9+)
print(*xs, sep=", ") # splat a list into args
Decorators & generators #
from functools import lru_cache
@lru_cache(maxsize=None) # memoize a pure function
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
def count_up(n):
yield from range(n) # delegate iteration to another iterable