Skip to content

Instantly share code, notes, and snippets.

@Rafael09ED
Last active August 3, 2026 18:51
Show Gist options
  • Select an option

  • Save Rafael09ED/79b2e898fd8277d3dcd6211e295836d6 to your computer and use it in GitHub Desktop.

Select an option

Save Rafael09ED/79b2e898fd8277d3dcd6211e295836d6 to your computer and use it in GitHub Desktop.
Python Syntax Reference

Python Syntax Reference

Table of Contents

  1. Core Syntax Rules
  2. For Loops & Control Flow
  3. Functions & Decorators
  4. Classes & OOP
  5. Error Handling
  6. Modern & Clever Features (3.8+)
  7. Modifying Lists
  8. File System Interaction
  9. Math Tools
  10. Standard Library Tour
  11. String Formatting Through the Ages

Core Syntax Rules

Indentation

if True:
    x = 1
    if True:
        y = 2

Scope — LEGB

x = "global"

def outer():
    x = "enclosing"
    def inner():
        x = "local"
        print(x)
    inner()

global / nonlocal

count = 0
def increment():
    global count
    count += 1

def outer():
    x = 0
    def inner():
        nonlocal x
        x += 1
    inner()

Block scope

if True:
    y = 5
print(y)

Mutability

def f(x):
    x += 1
a = 5
f(a)
print(a)   # 5

def g(lst):
    lst.append(4)
b = [1, 2, 3]
g(b)
print(b)   # [1, 2, 3, 4]

Mutable default argument

def f(items=[]):
    items.append(1)
    return items

def f(items=None):
    items = items if items is not None else []

Truthiness

if []: ...
if "0": ...
if 0.0: ...

is vs ==

a = [1, 2]
b = [1, 2]
a == b      # True
a is b       # False

x = None
x is None

a = 256; b = 256
a is b       # True
a = 257; b = 257
a is b       # False

Operator precedence

1 < 2 < 3
2 + 3 * 4          # 14
2 ** 3 ** 2         # 512

and / or

x = None
y = x or "default"
z = a and b

Division & modulo

7 / 2          # 3.5
7 // 2         # 3
7 % 2          # 1
-7 // 2        # -4
-7 % 2         # 1

Strings

'single' == "double"
"""triple"""

"a" "b"

s = "hello"
s[0]           # 'h'
s[0] = 'H'      # error

r"raw\nstring"
b"bytes"

Objects

def f(): pass
f.__name__
type(f)
isinstance(5, int)
callable(f)

funcs = [str.upper, str.lower]
funcs[0]("hi")

Assignment

a = b = c = 0
a, b = b, a

x: int = 5
x: int

Cross-type comparison

1 == 1.0        # True
True == 1        # True
"1" == 1          # False

Function arguments

def f(a, b=1, *args, c, d=2, **kwargs):
    ...

f(1, c=3)
f(1, 2, 3, 4, c=5, e=6)

def f(a, b=1, c):   # SyntaxError
    ...

Positional-only / keyword-only

def f(a, b, /, c, *, d):
    ...

Unpacking

def f(a, b, c): ...
args = [1, 2, 3]
f(*args)

kwargs = {"a": 1, "b": 2, "c": 3}
f(**kwargs)

first, *rest = [1, 2, 3, 4]
merged = [*list1, *list2]
merged_dict = {**d1, **d2}

Late binding closures

funcs = [lambda: i for i in range(3)]
[f() for f in funcs]   # [2, 2, 2]

funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]    # [0, 1, 2]

Comments & docstrings

# comment

def f():
    """Docstring."""
    pass

None, Ellipsis

None
...
def f(): ...

Line continuation

a = 1; b = 2

total = 1 + \
        2 + \
        3

total = (1 +
         2 +
         3)

For Loops & Control Flow

for item in [1, 2, 3]:
    print(item)

for i in range(5):
for i in range(2, 10, 2):
for i in range(10, 0, -1):

n = 5
while n > 0:
    print(n)
    n -= 1

for x in items:
    if x is None:
        continue
    if x == "stop":
        break

for x in items:
    if x == target:
        break
else:
    print("not found")

for i, row in enumerate(grid):
    for j, val in enumerate(row):
        print(i, j, val)

for key in d:
for key, val in d.items():
for val in d.values():

for name, age in zip(names, ages):
    print(name, age)

for x in reversed([1, 2, 3]):
    print(x)

for p in sorted(people, key=lambda p: p.age, reverse=True):
    print(p)

if x > 0:
    sign = "positive"
elif x < 0:
    sign = "negative"
else:
    sign = "zero"

if "a" in "cat": ...
if x not in blacklist: ...

while True:
    cmd = input("> ")
    if cmd == "quit":
        break

result = []
for x in items:
    if x > 0:
        result.append(x)

result = [x for x in items if x > 0]

for x in items:
    pass

for x, y in [(1, 2), (3, 4)]:
    print(x + y)

Functions & Decorators

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(time.time() - start)
        return result
    return wrapper

@timer
def slow(): ...

from functools import wraps

def decorator(func):
    @wraps(func)
    def wrapper(*a, **kw): return func(*a, **kw)
    return wrapper

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

from functools import partial
add5 = partial(lambda a, b: a + b, 5)
add5(10)

from functools import reduce
reduce(lambda a, b: a * b, [1,2,3,4])

sorted(people, key=lambda p: p.age)
list(map(str.upper, words))
list(filter(lambda x: x > 0, nums))

Classes & OOP

class Vec:
    def __init__(self, x, y): self.x, self.y = x, y
    def __add__(self, o): return Vec(self.x+o.x, self.y+o.y)
    def __repr__(self): return f"Vec({self.x}, {self.y})"
    def __eq__(self, o): return (self.x, self.y) == (o.x, o.y)

class Circle:
    def __init__(self, r): self._r = r
    @property
    def area(self): return 3.14159 * self._r ** 2

class Date:
    @classmethod
    def from_string(cls, s): return cls(*map(int, s.split("-")))
    @staticmethod
    def is_valid(s): return len(s.split("-")) == 3

class Countdown:
    def __init__(self, n): self.n = n
    def __iter__(self): return self
    def __next__(self):
        if self.n <= 0: raise StopIteration
        self.n -= 1
        return self.n + 1

class Timer:
    def __enter__(self): self.start = time.time(); return self
    def __exit__(self, *exc): print(time.time() - self.start)

with Timer():
    do_work()

from contextlib import contextmanager

@contextmanager
def open_resource():
    r = acquire()
    try:
        yield r
    finally:
        release(r)

class A: pass
class B: pass
class C(A, B): pass
print(C.__mro__)

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self): ...

class Positive:
    def __set_name__(self, owner, name): self.name = name
    def __get__(self, obj, type=None): return obj.__dict__[self.name]
    def __set__(self, obj, value):
        if value < 0: raise ValueError("must be positive")
        obj.__dict__[self.name] = value

class Product:
    price = Positive()

class Meta(type):
    def __new__(mcs, name, bases, ns):
        ns['created_by'] = 'Meta'
        return super().__new__(mcs, name, bases, ns)

class Foo(metaclass=Meta): pass

Error Handling

try:
    risky()
except ValueError as e:
    handle(e)
else:
    print("no error occurred")
finally:
    cleanup()

class InsufficientFundsError(Exception):
    def __init__(self, amount):
        self.amount = amount
        super().__init__(f"short by {amount}")

try:
    parse(data)
except ValueError as e:
    raise ConfigError("bad config") from e

try:
    ...
except* ValueError as eg:
    for e in eg.exceptions:
        print(e)

Modern & Clever Features (3.8+)

if (n := len(data)) > 10:
    print(f"too long: {n}")

match command.split():
    case ["go", direction]:
        move(direction)
    case ["attack", *targets]:
        attack(targets)
    case {"action": "jump", "height": h}:
        jump(h)
    case Point(x=0, y=0):
        print("origin")
    case _:
        print("unknown")

x = 5
print(f"{x=}")

def first(items: list[int]) -> int | None:
    return items[0] if items else None

type Vector = list[float]

from dataclasses import dataclass

@dataclass(slots=True, frozen=True)
class Point:
    x: float
    y: float

from functools import cache

@cache
def fib(n): return n if n < 2 else fib(n-1) + fib(n-2)

merged = dict_a | dict_b
dict_a |= dict_b

first, *middle, last = [1, 2, 3, 4, 5]

with open("a") as a, open("b") as b:
    ...

from contextlib import suppress

with suppress(FileNotFoundError):
    os.remove("gone.txt")

from enum import Enum, auto

class Color(Enum):
    RED = auto()
    GREEN = auto()

from itertools import pairwise, batched

list(pairwise([1,2,3,4]))
list(batched(range(7), 3))

def flatten(nested):
    for item in nested:
        yield from item

import asyncio

async def main():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(fetch(url1))
        tg.create_task(fetch(url2))

from typing import Self

class Builder:
    def add(self, x) -> Self:
        return self

from typing import Protocol

class Sized(Protocol):
    def __len__(self) -> int: ...

Modifying Lists

lst = [1, 2, 3]

lst.append(4)
lst.insert(1, "x")
lst.extend([5, 6])
lst += [7, 8]
lst = lst + [9]

lst.remove("x")
lst.pop()
lst.pop(0)
del lst[0]
del lst[1:3]
lst.clear()

lst[0] = 100
lst[1:3] = [10, 20, 30]
lst[::2] = [0, 0, 0]

lst.sort()
lst.sort(reverse=True)
lst.sort(key=lambda x: -x)
lst.reverse()

sorted(lst)
list(reversed(lst))

lst.index(3)
lst.count(3)
3 in lst

a = [1, 2, 3]
b = a
b.append(4)

c = a.copy()
c = a[:]
import copy
d = copy.deepcopy(a)

lst.sort()
new = sorted(lst)

lst.append(5)
new = lst + [5]

doubled = [x * 2 for x in lst]
filtered = [x for x in lst if x > 0]
lst[:] = [x for x in lst if x > 0]

combined = lst1 + lst2
lst1.extend(lst2)

lst[:] = list(dict.fromkeys(lst))

grid = [[0]*3 for _ in range(3)]
grid[0][1] = 5

import numpy as np
arr = np.array([1, 2, 3])

arr[0] = 100
arr = np.append(arr, 4)
arr = np.delete(arr, 1)
arr = np.insert(arr, 0, -1)
arr += 10
mask = arr > 0
arr = arr[mask]

File System Interaction

from pathlib import Path

p = Path("data/file.txt")
p.exists()
p.is_file()
p.is_dir()
p.name
p.stem
p.suffix
p.parent
p.resolve()

p.mkdir(parents=True, exist_ok=True)
p.write_text("hello")
content = p.read_text()
p.write_bytes(b"data")

for f in Path(".").iterdir():
    print(f)
for f in Path(".").glob("**/*.py"):
    print(f)

with open("file.txt") as f:
    content = f.read()
    lines = f.readlines()
    for line in f:
        process(line)

with open("out.txt", "w") as f:
    f.write("hello\n")

with open("log.txt", "a") as f:
    f.write("more\n")

import os

os.getcwd()
os.chdir("/tmp")
os.listdir(".")
os.rename("old.txt", "new.txt")
os.remove("file.txt")
os.path.join("dir", "file.txt")
os.path.getsize("file.txt")
os.walk(".")
for root, dirs, files in os.walk("."):
    for f in files:
        print(os.path.join(root, f))

import shutil
shutil.copy("a.txt", "b.txt")
shutil.copytree("src_dir", "dst_dir")
shutil.move("a.txt", "archive/")
shutil.rmtree("old_dir")
shutil.make_archive("backup", "zip", "my_folder")

import tempfile

with tempfile.TemporaryDirectory() as d:
    ...
with tempfile.NamedTemporaryFile(delete=False) as f:
    f.write(b"data")

import zipfile
with zipfile.ZipFile("archive.zip") as z:
    z.extractall("out/")
    z.namelist()

import tarfile
with tarfile.open("archive.tar.gz") as t:
    t.extractall("out/")

Math Tools

import math

math.sqrt(16)
math.pow(2, 10)
math.floor(3.7), math.ceil(3.2)
math.log(100, 10)
math.exp(1)
math.factorial(5)
math.gcd(12, 18)
math.isclose(0.1+0.2, 0.3)
math.pi, math.e, math.inf, math.nan
math.hypot(3, 4)

import statistics as stats

stats.mean([1, 2, 3, 4])
stats.median([1, 2, 3, 4])
stats.mode([1, 1, 2, 3])
stats.stdev([1, 2, 3, 4])
stats.variance([1, 2, 3, 4])

import random

random.random()
random.uniform(1, 10)
random.randint(1, 6)
random.choice(["a","b","c"])
random.sample(range(100), 5)
random.shuffle(my_list)
random.seed(42)

from decimal import Decimal, getcontext
getcontext().prec = 10
Decimal("0.1") + Decimal("0.2")

from fractions import Fraction
Fraction(1, 3) + Fraction(1, 6)
Fraction(0.5)

import cmath
cmath.sqrt(-1)

import numpy as np

arr = np.array([1, 2, 3])
np.mean(arr), np.std(arr), np.sum(arr)
np.dot(a, b)
np.linalg.inv(matrix)
np.linalg.solve(A, b)
arr.reshape(3, 1)
np.arange(0, 10, 0.5)
np.linspace(0, 1, 100)

from scipy import optimize, stats

optimize.minimize(func, x0)
stats.norm.pdf(x, loc=0, scale=1)
stats.ttest_ind(sample1, sample2)

Standard Library Tour

from collections import Counter, defaultdict, namedtuple, deque, OrderedDict, ChainMap

Counter("banana")
defaultdict(int)
deque([1,2,3], maxlen=5)

from itertools import chain, product, combinations, permutations, groupby, islice

list(product([1,2], ['a','b']))
list(islice(range(100), 5))

import heapq
h = [3,1,4,1,5]
heapq.heapify(h)
heapq.heappush(h, 2)
heapq.heappop(h)

import bisect
bisect.insort(sorted_list, 5)

from functools import lru_cache, reduce, partial, cached_property

@lru_cache(maxsize=None)
def fib(n): return n if n < 2 else fib(n-1)+fib(n-2)

from operator import itemgetter, attrgetter
sorted(people, key=attrgetter('age'))
sorted(pairs, key=itemgetter(1))

import re
re.findall(r'\d+', "a1 b22 c333")
re.sub(r'\s+', ' ', "too    many  spaces")

import textwrap
textwrap.fill(long_text, width=40)

import json
json.dumps({"a": 1})
json.loads('{"a": 1}')

import csv
with open("f.csv") as f:
    for row in csv.reader(f):
        print(row)

from datetime import datetime, timedelta
now = datetime.now()
now + timedelta(days=7)
now.strftime("%Y-%m-%d")

import time
time.sleep(1)
time.time()

import calendar
calendar.isleap(2024)

import sys
sys.argv
sys.exit(1)
sys.path

import subprocess
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", required=True)
args = parser.parse_args()

import logging
logging.basicConfig(level=logging.INFO)
logging.info("started")

import threading
t = threading.Thread(target=worker)
t.start(); t.join()

from multiprocessing import Pool
with Pool(4) as p:
    results = p.map(func, data)

import asyncio
async def main():
    await asyncio.sleep(1)
    print("done")
asyncio.run(main())

from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as ex:
    results = list(ex.map(fetch, urls))

from urllib.request import urlopen
urlopen("https://example.com").read()

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

import pickle
pickle.dumps(obj)
pickle.loads(data)

import hashlib
hashlib.sha256(b"data").hexdigest()

import base64
base64.b64encode(b"data")

import uuid
uuid.uuid4()

import unittest
class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1 + 1, 2)

def add(a, b):
    """
    >>> add(2, 3)
    5
    """
    return a + b

import pdb; pdb.set_trace()

import timeit
timeit.timeit("sum(range(100))", number=10000)

import copy
copy.deepcopy(nested_obj)

from typing import Optional, Union, Callable
def f(x: Optional[int] = None) -> Union[int, str]: ...

from enum import Enum
class Color(Enum):
    RED = 1
    GREEN = 2

from dataclasses import dataclass
@dataclass
class Point:
    x: int
    y: int

from contextlib import contextmanager, suppress

import inspect
inspect.signature(some_func)
inspect.getsource(some_func)

String Formatting Through the Ages

"%s is %d" % (name, age)
"{} is {}".format(name, age)
f"{name} is {age}"
f"{name!r} is {age:>5}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment