Stdlib Power Tools — Cheat Sheet
Python A–Z · 5 topics. Download the PDF or the Instagram carousel and share it.
collections — Counter, defaultdict & deque
Counter counts anything in one line, defaultdict removes key-existence boilerplate, deque gives O(1) queues — three imports that shorten half of all interview solutions.
- ✓Counter: most_common(k), zero for missing keys, arithmetic between counters
- ✓defaultdict(list) for grouping, defaultdict(int) for counting — no key checks
- ✓deque: O(1) append/pop on both ends — always use it for BFS queues
- ✓Counter(a) == Counter(b) is the cleanest anagram test
from collections import Counter
votes = ["asha", "ravi", "asha", "neha", "asha", "ravi"]
c = Counter(votes)
print(c) # Counter({'asha': 3, 'ravi': 2, 'neha': 1})
print(c.most_common(2)) # [('asha', 3), ('ravi', 2)]
print(c["missing"]) # 0 — no KeyError!
# Anagram check — one line
print(Counter("listen") == Counter("silent")) # True
# Top-K frequent elements (LeetCode 347) — two lines
nums = [1, 1, 1, 2, 2, 3]
print([n for n, _ in Counter(nums).most_common(2)]) # [1, 2]
# Counter arithmetic — "can I build this word from these letters?"
letters = Counter("aabbcc")
word = Counter("abc")
print(not (word - letters)) # True — nothing missingitertools & functools — lru_cache, product, groupby & reduce
@lru_cache memoizes recursion in one decorator line; itertools generates combinations, permutations and products lazily — brute-force search and DP speedups for free.
- ✓@lru_cache memoizes by arguments (hashable only) — instant DP from recursion
- ✓combinations = unordered picks, permutations = ordered, product = nested loops
- ✓accumulate gives prefix sums; groupby groups CONSECUTIVE items (sort first!)
- ✓Everything in itertools is lazy — islice to take a finite window
from functools import lru_cache
@lru_cache(maxsize=None) # or @cache in 3.9+
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(100)) # instant — 354224848179261915075
print(fib.cache_info()) # hits=98 misses=101 ...
# Classic DP: climbing stairs / ways to reach n
@lru_cache(maxsize=None)
def ways(n):
if n <= 1:
return 1
return ways(n - 1) + ways(n - 2)
# functools.partial — pre-fill arguments
from functools import partial
def power(base, exp): return base ** exp
square = partial(power, exp=2)
print(square(9)) # 81
# functools.reduce — fold a sequence (use sparingly)
from functools import reduce
print(reduce(lambda a, b: a * b, [1, 2, 3, 4])) # 24datetime — Dates, Timezones & Durations
datetime + timedelta do date arithmetic; strftime/strptime convert to and from strings; and timezone-aware UTC datetimes are the only correct choice for backends.
- ✓datetime - datetime = timedelta; datetime + timedelta = datetime
- ✓strptime parses strings in, strftime formats out; ISO-8601 via isoformat()
- ✓Store/compute in aware UTC — datetime.now(timezone.utc); convert to IST only for display
- ✓Naive and aware datetimes cannot be compared — pick aware, everywhere
from datetime import datetime, timedelta, date
now = datetime.now()
placement_day = datetime(2026, 12, 1, 9, 0)
gap = placement_day - now # timedelta
print(gap.days, "days left")
token_expiry = now + timedelta(hours=12)
print(now < token_expiry) # True
# Date-only math
today = date.today()
last_monday = today - timedelta(days=today.weekday())
print("week started:", last_monday)
# timedelta knows seconds too
print(timedelta(days=1).total_seconds()) # 86400.0
# Compare timestamps naturally
t1 = datetime(2026, 7, 10, 14, 30)
t2 = datetime(2026, 7, 10, 18, 0)
print(max(t1, t2)) # later oneRegular Expressions — the re Module
search finds, findall collects, sub replaces, groups extract — with raw strings, character classes and quantifiers making Python a text-processing power tool.
- ✓Always raw strings: r"\d+" — otherwise Python eats your backslashes
- ✓search anywhere vs match at start; findall returns group contents
- ✓.* is greedy (longest), .*? is lazy (shortest) — the #1 regex bug
- ✓Groups (...) extract; named groups (?P<name>...) document; \b bounds whole words
import re
log = "2026-07-10 ERROR user=asha code=500; 2026-07-10 INFO user=ravi code=200"
# search — first occurrence anywhere
m = re.search(r"code=(\d+)", log)
print(m.group(0), m.group(1)) # code=500 500
# findall — everything, capture groups only
print(re.findall(r"user=(\w+)", log)) # ['asha', 'ravi']
# sub — replace (mask phone numbers)
txt = "call 9876543210 or 9123456789"
print(re.sub(r"\d{10}", "XXXXXXXXXX", txt))
# Named groups — self-documenting extraction
pat = re.compile(r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<level>\w+)")
for m in pat.finditer(log):
print(m["date"], m["level"]) # 2026-07-10 ERROR / INFO
# match vs search: match anchors at position 0
print(re.match(r"\d+", "abc123")) # None
print(re.search(r"\d+", "abc123")) # <re.Match ... '123'>Logging — Beyond print()
The logging module gives leveled, timestamped, routable logs — DEBUG/INFO/WARNING/ERROR/CRITICAL — configured once and used via module-level loggers; print() is for humans, logging is for systems.
- ✓getLogger(__name__) per module; configure levels/handlers once at the entry point
- ✓DEBUG for dev detail, INFO for lifecycle, WARNING for smells, ERROR/CRITICAL for failures
- ✓logger.exception() inside except logs the traceback automatically
- ✓Use %-style lazy args in log calls; f-strings evaluate even when filtered out
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)-8s %(name)s: %(message)s",
datefmt="%H:%M:%S",
)
logger = logging.getLogger(__name__) # per-module logger
logger.debug("cache warm-up details") # hidden (below INFO)
logger.info("server started on :8000")
logger.warning("disk 85% full")
logger.error("payment gateway timed out")
# 14:02:11 INFO __main__: server started on :8000
# 14:02:11 WARNING __main__: disk 85% full
# 14:02:11 ERROR __main__: payment gateway timed out
# Lazy formatting — string built ONLY if the level passes
user_id, ms = "asha", 42
logger.info("user %s served in %d ms", user_id, ms) # preferred
# vs logger.info(f"user {user_id}...") — f-string always evaluates