🐍 Pythonic Ways — The Ultimate Guide


 
# -----------------------------
# 1. Collections & Basics
# -----------------------------
 
lst = []                      # empty list
lst = list("hello")           # from iterable → ['h','e','l','l','o']
nums = [0] * 5                # repeat value → [0,0,0,0,0]
 
squares = [x*x for x in range(5)]         # list comprehension
evens   = [x for x in range(10) if x%2==0]# with condition
unique  = {x%3 for x in range(10)}        # set comprehension
mapping = {x: x**2 for x in range(5)}     # dict comprehension
 
a, b, c = (1, 2, 3)           # tuple unpacking
x, y = y, x                   # swap without temp
 
 
# -----------------------------
# 2. Iteration
# -----------------------------
 
for i, val in enumerate(['a','b']):  # enumerate → index + value
    print(i, val)
 
for a, b in zip([1,2], ['x','y']):   # zip → parallel iteration
    print(a, b)
 
from itertools import product
print(list(product([0,1], repeat=2))) # cartesian product [(0,0),(0,1),(1,0),(1,1)]
 
# loop with else (executes if no break)
for n in [3,5,7]:
    if n % 2 == 0:
        break
else:
    print("no even number found")
 
 
# -----------------------------
# 3. Conditionals
# -----------------------------
 
msg = "even" if x%2==0 else "odd"    # inline if-else
if lst: print("not empty")           # truthiness
if not s: print("empty string")
 
if any(x>10 for x in nums): ...      # any → at least one true
if all(x>=0 for x in nums): ...      # all → all true
 
labels = ["even" if n%2==0 else "odd" for n in range(5)]  # ternary in comprehension
 
 
# -----------------------------
# 4. Functions
# -----------------------------
 
def greet(name="World"):             # default arg
    print(f"Hello {name}")
 
def f(*args, **kwargs):              # arbitrary args
    print(args, kwargs)
 
add = lambda a,b: a+b                # small lambda
 
from functools import reduce
total = reduce(lambda a,b: a+b, [1,2,3])  # higher-order
 
def countdown(n):                    # generator
    while n > 0:
        yield n
        n -= 1
 
 
# -----------------------------
# 5. Strings
# -----------------------------
 
name = "Alice"
print(f"Hello {name}, 2+2={2+2}")     # f-string
print(", ".join(["a","b","c"]))       # join
print("  hi  ".strip())               # strip whitespace
print("a,b,c".split(","))             # split
text = """multi
line"""                               # multiline string
 
 
# -----------------------------
# 6. Data Structures
# -----------------------------
 
seen = set(nums)                      # set for uniqueness
 
from collections import defaultdict, Counter
counts = defaultdict(int)             # dict with default
for ch in "banana": counts[ch]+=1
 
print(Counter("banana"))              # Counter → counts chars
 
from dataclasses import dataclass
@dataclass
class Point:                           # dataclass auto-creates init, repr, eq
    x: int
    y: int = 0
 
 
# -----------------------------
# 7. Error Handling
# -----------------------------
 
try:
    1/0
except ZeroDivisionError:
    print("oops")
else:
    print("no error")
finally:
    print("always runs")
 
# EAFP style (try/except instead of checking)
try:
    val = d["key"]
except KeyError:
    val = None
 
 
# -----------------------------
# 8. With (Context Managers)
# -----------------------------
 
with open("file.txt") as f:          # auto-closes file
    data = f.read()
 
from contextlib import contextmanager
@contextmanager
def temp():
    print("enter")
    yield
    print("exit")
 
 
# -----------------------------
# 9. Classes
# -----------------------------
 
class Dog:                            # basic class
    def __init__(self, name):
        self.name = name
 
@dataclass                            # dataclass shortcut
class Cat:
    name: str
    age: int = 0
 
class C:                              # property
    def __init__(self): self._x = 0
    @property
    def x(self): return self._x
    @x.setter
    def x(self,val): self._x = val
 
 
# -----------------------------
# 10. Idioms & Shortcuts
# -----------------------------
 
if (n := len(lst)) > 5: print(n)      # walrus operator
flat = [x for row in grid for x in row] # flatten 2D
transposed = list(zip(*grid))         # transpose matrix
merged = dict1 | dict2                # dict merge (3.9+)
 
print(f"{x=}")                        # f-string debug → x=42
 
assert x > 0, "x must be positive"    # assert
 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ============================================
# Pythonic Cookbook — Idioms & Best Practices
# Run me as a single script.
# ============================================
 
print("\n=== 1) Collections & Basics ===")
 
# Empty / from iterable / repeated values
lst = []                                # empty list
lst2 = list("hello")                    # from iterable → ['h','e','l','l','o']
nums = [0] * 5                          # repeat value -> [0,0,0,0,0]
print("lst2:", lst2)
print("nums:", nums)
 
# Comprehensions (list / set / dict)
squares = [x*x for x in range(6)]       # list comp
evens   = [x for x in range(10) if x%2==0]
mods    = {x % 3 for x in range(10)}    # set comp -> {0,1,2}
powmap  = {x: x**2 for x in range(5)}   # dict comp -> {0:0, 1:1, 2:4, 3:9, 4:16}
print("squares:", squares)
print("evens:", evens)
print("mods:", mods)
print("powmap:", powmap)
 
# Tuple packing/unpacking + swapping
a, b, c = (1, 2, 3)
x, y = 10, 20
x, y = y, x                             # swap without temp
print("unpack a,b,c:", a, b, c, "| swapped x,y:", x, y)
 
# Slicing / cloning
clone1 = lst2[:]                         # clone via slice
clone2 = lst2.copy()                     # clone via .copy()
clone3 = list(lst2)                      # clone via constructor
print("clone checks:", clone1 == clone2 == clone3 == lst2)
 
# --------------------------------------------
 
print("\n=== 2) Iteration Patterns ===")
 
# enumerate: index + value
for i, ch in enumerate("abc"):
    if i == 0:
        print("enumerate:", i, ch)
 
# zip: parallel iteration
for a, b in zip([1,2,3], ["x","y","z"]):
    print("zip pair:", a, b)
    break
 
# itertools power-ups
from itertools import product, permutations, combinations, repeat, chain
print("product([0,1], repeat=2):", list(product([0,1], repeat=2)))
print("permutations('abc',2):", list(permutations("abc", 2)))
print("combinations('abc',2):", list(combinations("abc", 2)))
print("repeat(7, 4):", list(repeat(7, 4)))
print("chain:", list(chain([1,2], [3], (4,5))))
 
# for-else (runs else if loop didn't break)
for n in [3, 5, 7]:
    if n % 2 == 0:  # never true
        break
else:
    print("for-else: no even number found")
 
# --------------------------------------------
 
print("\n=== 3) Conditionals, Truthiness, Any/All ===")
 
n = 5
msg = "even" if n % 2 == 0 else "odd"   # inline if-else (ternary)
print("ternary msg:", msg)
 
# Truthiness: empty containers are falsy
if []: 
    pass
else:
    print("truthiness: [] is falsy")
 
nums2 = [1, 3, 11, -2]
print("any > 10?:", any(x > 10 for x in nums2))
print("all >= -2?:", all(x >= -2 for x in nums2))
 
labels = ["even" if k%2==0 else "odd" for k in range(6)]
print("labels:", labels)
 
# --------------------------------------------
 
print("\n=== 4) Functions, *args/**kwargs, Lambdas, Generators ===")
 
def greet(name="World"):                 # default arg + f-string
    return f"Hello, {name}"
 
def demo_star_args(*args, **kwargs):     # arbitrary args
    return args, kwargs
 
adder = lambda a, b: a + b               # tiny throwaway lambda
 
from functools import reduce
total = reduce(lambda a,b: a+b, [1,2,3,4])
 
def countdown(n):                        # generator using yield
    while n > 0:
        yield n
        n -= 1
 
print(greet(), "|", greet("Alice"))
print("star-args:", demo_star_args(1,2, k=3))
print("adder(3,4):", adder(3,4))
print("reduce sum:", total)
print("countdown:", list(countdown(3)))
 
# --------------------------------------------
 
print("\n=== 5) Strings & Text ===")
 
name = "Bob"
print(f"f-string demo: 2+2={2+2}, name={name}")
print("join:", ", ".join(["a","b","c"]))
print("strip:", "  hi  ".strip())
print("split:", "a,b,c".split(","))
 
multiline = """Line1
Line2
Line3"""
print("multiline lines:", multiline.count("\n") + 1)
 
# Useful string predicates
s = "Abc123"
print("isdigit/isalpha/isupper:", s.isdigit(), s.isalpha(), s.isupper())
 
# --------------------------------------------
 
print("\n=== 6) Data Structures Beyond Lists ===")
 
# Sets for uniqueness
print("unique with set:", set("banana"))
 
# Dict with defaults: defaultdict
from collections import defaultdict, Counter, deque, namedtuple
counts = defaultdict(int)
for ch in "banana":
    counts[ch] += 1
print("defaultdict counts:", dict(counts))
 
# Counter: quick frequency table
print("Counter:", Counter("mississippi"))
 
# Deque: fast appends/pops at both ends
dq = deque([1,2,3])
dq.appendleft(0)   # [0,1,2,3]
dq.append(4)       # [0,1,2,3,4]
dq.pop()           # remove rightmost -> 4
dq.popleft()       # remove leftmost -> 0
print("deque:", dq)
 
# Namedtuple (simple record) and Dataclass (modern)
PointNT = namedtuple("PointNT", "x y")
pnt = PointNT(2, 5)
print("namedtuple:", pnt, pnt.x, pnt.y)
 
from dataclasses import dataclass
 
@dataclass
class Point:
    x: int
    y: int = 0
 
p = Point(3)  # y defaults to 0
print("dataclass:", p)
 
# Array (homogeneous, memory-efficient) optional demo
from array import array
arr = array('i', [1,2,3])  # 'i' = signed int
print("array('i'):", arr.tolist())
 
# --------------------------------------------
 
print("\n=== 7) Error Handling & EAFP ===")
 
try:
    1/0
except ZeroDivisionError:
    print("caught ZeroDivisionError")
else:
    print("no error happened")          # will not run
finally:
    print("finally always runs")
 
# EAFP (Easier to Ask Forgiveness than Permission)
d = {"a": 1}
try:
    val = d["missing"]
except KeyError:
    val = None
print("EAFP val:", val)
 
# --------------------------------------------
 
print("\n=== 8) Context Managers (with) ===")
 
# Files auto-close
from pathlib import Path
tmpfile = Path("tmp_demo.txt")
with open(tmpfile, "w", encoding="utf-8") as f:
    f.write("hello\n")
 
with open(tmpfile, "r", encoding="utf-8") as f:
    print("file read:", f.read().strip())
 
# Custom context manager
from contextlib import contextmanager
 
@contextmanager
def demo_context(label):
    print(f"[enter {label}]")
    try:
        yield
    finally:
        print(f"[exit  {label}]")
 
with demo_context("X"):
    print("doing work inside context")
 
tmpfile.unlink(missing_ok=True)  # clean up
 
# --------------------------------------------
 
print("\n=== 9) Classes, Properties, Dunder Methods ===")
 
class Dog:
    def __init__(self, name):           # constructor
        self.name = name
 
    def __repr__(self):                 # nice debug string
        return f"Dog(name={self.name!r})"
 
d1 = Dog("Rex")
print("Dog repr:", d1)
 
@dataclass
class Cat:
    name: str
    age: int = 0
 
c1 = Cat("Mimi", 2)
print("Dataclass Cat:", c1)
 
class Celsius:
    def __init__(self, temp=0):
        self._temp = temp
 
    @property
    def temperature(self):              # getter
        return self._temp
 
    @temperature.setter
    def temperature(self, value):       # setter
        if value < -273.15:
            raise ValueError("below absolute zero")
        self._temp = value
 
cel = Celsius(25)
cel.temperature = 30
print("property getter:", cel.temperature)
 
# --------------------------------------------
 
print("\n=== 10) Idioms & Shortcuts ===")
 
# Walrus operator := (assign within expressions)
if (ln := len(squares)) > 5:
    print("walrus len:", ln)
 
# Flatten a 2D list; transpose with zip(*)
grid = [[0]*3 for _ in range(2)]
flat = [x for row in grid for x in row]
transposed = list(zip(*grid))
print("flat:", flat)
print("transposed:", transposed)
 
# Dict merge (3.9+)
d1, d2 = {"a":1}, {"b":2}
merged = d1 | d2
print("dict merge:", merged)
 
# F-string debug (3.8+)
x = 42
print(f"debug: {x=}")                  # prints "x=42"
 
# Assertions (lightweight checks)
assert 2 + 2 == 4, "math broke"
print("assertion passed")
 
# --------------------------------------------
 
print("\n=== 11) Sorting, Key Functions, Stable Sort ===")
 
items = ["apple", "kiwi", "banana", "fig"]
print("sorted alpha:", sorted(items))
print("sorted by len:", sorted(items, key=len))
print("sorted by last char:", sorted(items, key=lambda s: s[-1]))
# Stability demo: sort by len, then alpha within same length
print("stable sort:",
      sorted(sorted(items), key=len))
 
# --------------------------------------------
 
print("\n=== 12) Generators, Iterables, Lazy Evaluation ===")
 
def read_lines_upper(text):
    # Example generator pipeline
    for line in text.splitlines():
        line = line.strip()
        if line:
            yield line.upper()
 
sample = "  a\n\nb  \n c "
print("gen pipeline:", list(read_lines_upper(sample)))
 
# Generator expressions (lazy)
squares_lazy = (n*n for n in range(5))
print("lazy next:", next(squares_lazy), next(squares_lazy))
print("lazy rest:", list(squares_lazy))
 
# --------------------------------------------
 
print("\n=== 13) Datetime & Pathlib (pythonic stdlib) ===")
 
from datetime import datetime, timedelta, timezone
now = datetime.now(timezone.utc)
tomorrow = now + timedelta(days=1)
print("now UTC:", now.isoformat())
print("tomorrow UTC:", tomorrow.isoformat())
 
from pathlib import Path
p = Path(".") / "some" / "nested" / "file.txt"
print("pathlib join:", p)
print("parent exists?:", p.parent.exists())
 
# --------------------------------------------
 
print("\n=== 14) 2D/N-D Arrays with NumPy (when numeric) ===")
 
try:
    import numpy as np
    mat = np.zeros((2,3), dtype=int)
    mat[0, 1] = 7
    print("numpy mat:\n", mat)
except ImportError:
    print("NumPy not installed; skipping demo")
 
# --------------------------------------------
 
print("\n=== 15) Performance Tips (micro) ===")
 
# Use builtins: sum/min/max/any/all instead of manual loops
nums3 = [3, 1, 4, 1, 5]
print("sum/min/max:", sum(nums3), min(nums3), max(nums3))
 
# Pre-bind methods for tight loops (advanced micro-opt)
join = ", ".join
print("prebound join:", join(["A","B","C"]))
 
print("\nAll demos complete ✅")
 

✅ Philosophy

  • Prefer comprehensions over loops.
  • Prefer with over manual open/close.
  • Prefer EAFP (try/except) over checking everything first.
  • Prefer built-ins & standard lib (sum, max, min, any, all) over manual loops.
  • Write readable, concise, intention-revealing code.