18. Common Interview Pitfalls & Patterns

Know the classics; avoid traps that signal weak fundamentals.

Question: Why are mutable default arguments a problem in Python?

Answer: Default arguments are evaluated only once, when the function is defined, not each time it's called. If a mutable object like a list or dictionary is used as a default, it will be shared across all calls to that function, leading to unexpected behavior.

Explanation: The standard pattern to avoid this is to use None as the default and then create a new mutable object inside the function if the argument is None.

# Correct way to handle mutable defaults
def f(x, acc=None):
    if acc is None:
        acc = []
    acc.append(x)
    return acc

Question: What is late-binding in closures and how can it cause issues in loops?

Answer: Closures in Python bind to names, not values. In a loop, if a lambda or inner function captures a loop variable, it will see the final value of that variable from the loop's last iteration, not the value it had when the function was defined.

Explanation: The classic solution is to force an early binding by passing the loop variable as a default argument to the inner function. This creates a new scope and captures the value at that specific iteration.

# The `i=i` captures the value of i at each iteration
funcs = [lambda x, i=i: x + i for i in range(3)]
# funcs[0](10) returns 10, not 12

Question: What are timezone pitfalls with datetime and how to avoid them?

Answer: Naive datetimes lack timezone info and cause bugs. Use aware datetimes (zoneinfo) and store UTC in persistence layers.

Explanation: Convert to local time only at the edges.

from datetime import datetime, timezone
utc_now = datetime.now(tz=timezone.utc)

Question: Why can iterators be exhausted unexpectedly?

Answer: Many APIs consume iterators; reusing them later yields nothing. Materialize when needed.

Explanation: Prefer sequences for multiple passes.

it = (x for x in range(3))
list(it); list(it)  # second list(it) == []

Question: What are floating-point pitfalls?

Answer: Binary floats cannot exactly represent many decimals; comparisons can be surprising.

Explanation: Use tolerances or decimal for money.

from math import isclose
isclose(0.1 + 0.2, 0.3, rel_tol=1e-9)