Language-Specific Guides · 9 min read

Python for LeetCode: The Standard Library Cheat Sheet That Wins 15 Minutes Per Problem

If you are still writing your own heap, your own counter, and your own sorted-list, you are leaving fifteen minutes on the table.

1,573 words

Python is the most popular language in coding interviews and the one most candidates underuse. The reason is structural — interview prep teaches you the algorithms but rarely teaches you the standard library, so you end up reimplementing tools that ship with the language. A senior Python interviewer can spot a junior Python user in thirty seconds, not by their algorithm but by what they do not reach for. This article is the part of the standard library that pays the biggest dividends in a 45-minute window, plus the idioms that mark the candidate as fluent rather than merely literate.

collections — the workhorse module nobody opens

If your interview language is Python, learn collections cold. Counter, defaultdict, deque, and OrderedDict cover roughly a third of all interview support code. A candidate who writes their own frequency map by hand looks junior next to one who types Counter and moves on.

python
from collections import Counter, defaultdict, deque

# Counter: frequency map + arithmetic + most_common
cnt = Counter("anagram")          # Counter({'a': 3, 'n': 1, 'g': 1, 'r': 1, 'm': 1})
top_two = cnt.most_common(2)      # [('a', 3), ('n', 1)]
is_anagram = Counter(s) == Counter(t)

# defaultdict: skip the 'if key not in d' boilerplate
adj = defaultdict(list)
for u, v in edges:
    adj[u].append(v)
    adj[v].append(u)

# deque: O(1) appendleft/popleft for BFS, sliding window
queue = deque([root])
while queue:
    node = queue.popleft()
    for child in node.children:
        queue.append(child)

heapq — the heap you already have

Python's heapq is a min-heap on a list, in place. Every top-K, merge-K, and Dijkstra problem becomes one or two function calls. The trick most candidates miss: there is no max-heap, so push the negation. There is also no decrease-key, so for Dijkstra you push duplicates and skip stale entries on pop.

python
import heapq

# Top-K largest with O(n log k) using a min-heap of size k
def top_k(nums, k):
    h = []
    for x in nums:
        heapq.heappush(h, x)
        if len(h) > k:
            heapq.heappop(h)
    return sorted(h, reverse=True)

# Max-heap via negation
max_heap = []
for x in nums:
    heapq.heappush(max_heap, -x)
largest = -heapq.heappop(max_heap)

# Merge K sorted iterables (Dijkstra, k-way merge)
import heapq
merged = list(heapq.merge(list_a, list_b, list_c))

# Tuple ordering: heap on (priority, tiebreak, payload)
heapq.heappush(h, (cost, idx, node))

For Dijkstra specifically, the canonical pattern is: heap of (distance, node), maintain a dist[] dict, on pop check if the popped distance is greater than the recorded one and continue if so. That handles the no-decrease-key limitation with three lines of code.

bisect — binary search you do not have to write

Bisect is the module candidates most often forget exists. It is binary search on a sorted list with the off-by-one already correct. Use it for insertion-point problems, 'longest increasing subsequence' (the patience-sorting trick), and any 'find the smallest index where condition holds' question on a sorted structure.

python
from bisect import bisect_left, bisect_right, insort

idx = bisect_left(arr, target)    # leftmost insertion point
idx = bisect_right(arr, target)   # rightmost insertion point (1 past last equal)

# Maintain a sorted list as you insert
insort(sorted_arr, x)

# Longest increasing subsequence in O(n log n)
def length_of_lis(nums):
    tails = []
    for x in nums:
        i = bisect_left(tails, x)
        if i == len(tails):
            tails.append(x)
        else:
            tails[i] = x
    return len(tails)

itertools and functools — combinatorics and memoization

itertools owns the combinatorics part of backtracking interviews. permutations, combinations, product, accumulate, pairwise, chain — every one of these saves you a hand-rolled loop. functools.lru_cache and the newer @cache decorator turn naive recursion into memoized DP in one annotation.

python
from itertools import permutations, combinations, product, accumulate, pairwise
from functools import lru_cache, cache

for p in permutations([1, 2, 3]):     # all 6 orderings
    ...
for c in combinations(range(5), 2):   # all (i, j) with i < j
    ...
for pair in pairwise([1, 2, 3, 5]):   # (1,2), (2,3), (3,5)
    ...

running = list(accumulate([1, 2, 3, 4]))   # [1, 3, 6, 10]

@cache
def climb(n):
    if n <= 2: return n
    return climb(n - 1) + climb(n - 2)

The @cache decorator is the cleanest way to write top-down DP in Python. Define your recurrence, decorate, return the answer. The dict-backed memo handles tuple-keyed states, the recursion handles the order, and the code reads exactly like the recurrence on the whiteboard.

Strings, slicing, and the idioms that read fluent

Python strings have a denser set of helpers than candidates use. str.isalnum, str.isdigit, str.casefold (the right way to lower-case for comparison), str.translate (fast char-set transformations), and the slicing tricks that handle palindrome and reverse problems in one line.

IdiomWhat it doesWhen to use
s[::-1]reverse a string in O(n)palindrome checks, reverse-K problems
s.split()whitespace-split, handles multiple spacestokenizing input lines
zip(a, b, strict=True)pair iter, error on length mismatchcomparing sequences safely
enumerate(arr, start=1)indexed iteration with offset1-indexed problems
any(...) / all(...)short-circuit boolean foldvalidation, predicate over sequence
sorted(arr, key=..., reverse=...)key-based sortcustom-order problems

Type hints, comprehensions, and clean style

Modern interview Python uses type hints on function signatures (it documents intent for the interviewer in two seconds), comprehensions over explicit loops where readable, and dataclasses for any problem with a small record-shaped type.

python
from dataclasses import dataclass
from typing import Optional

@dataclass
class Interval:
    start: int
    end: int

def merge(intervals: list[Interval]) -> list[Interval]:
    intervals.sort(key=lambda i: i.start)
    out: list[Interval] = []
    for it in intervals:
        if out and it.start <= out[-1].end:
            out[-1] = Interval(out[-1].start, max(out[-1].end, it.end))
        else:
            out.append(it)
    return out
I can tell within the first thirty seconds whether a candidate writes Python every day or memorized it for the interview. Counter, deque, type hints, comprehensions — none of those are exotic. They are basic fluency.
Senior engineer, Python-heavy fintech

Common Python interview gotchas

Knowing the standard library only matters if you also know the language quirks that quietly bite. These are the Python-specific failure modes that come up most often in real interview sessions, the ones interviewers expect you to anticipate without being told.

  1. 1Mutable default arguments. `def f(x, acc=[])` keeps the same list across calls. Use `acc=None` and initialize inside the function.
  2. 2Late binding in closures. Lambdas inside a loop capture the variable, not the value. Bind the value with a default argument or a comprehension scope.
  3. 3Integer division and floor behavior. `-7 // 2` is `-4` in Python, not `-3`. `divmod` and explicit `int(x / y)` matter for problems with negative numbers.
  4. 4List vs tuple as dict keys. Lists are unhashable; tuples are. Memoization keyed on lists is the most common 'why does this crash' moment.
  5. 5Sort stability. Python's sort is stable, which lets you sort by secondary key first then primary. Useful trick for multi-key ordering without a custom comparator.
  6. 6Shallow vs deep copy. `[[0]*n]*m` gives you m references to the same row, not m independent rows. Use a list comprehension `[[0]*n for _ in range(m)]`.
python
# Mutable default arg trap
def append_bad(x, acc=[]):    # WRONG
    acc.append(x)
    return acc
append_bad(1); append_bad(2)  # returns [1, 2] on the second call

def append_ok(x, acc=None):
    if acc is None: acc = []
    acc.append(x)
    return acc

# Shallow-copy 2D init
grid_bad = [[0] * 3] * 3      # WRONG: 3 refs to same row
grid_bad[0][0] = 1            # mutates all rows
grid_ok = [[0] * 3 for _ in range(3)]   # 3 independent rows

Two more meta-points worth saying out loud. First, if you are using Python 3.9+ features (`a | b` for dict merge, `dict[str, int]` instead of `Dict[str, int]`, the walrus operator), confirm with the interviewer that the runtime supports them — most do, but some hiring rigs run older Python. Second, do not use exotic libraries you do not actually use day to day. Reaching for `numpy` to solve a string problem reads as 'I memorized a clever trick' and the interviewer will ask you to redo it in vanilla Python.

And one philosophy point. Python is a language where the right idiom is shorter and clearer than the wrong one. Senior Python on the whiteboard reads almost like prose. If your code looks like it could be C++ ported by a tool, you are leaving expressiveness — and ranking — on the table. Read clean Python code daily, not just to study but to absorb the rhythm of how fluent practitioners write. The interview pays back compound interest on that habit.

Stop grinding. Start patterning.

Alpha Code is a patterns-first interview prep platform — coding, system design, behavioral, mocks, and ML/AI engineering all under one $19/mo subscription.