Advertisement
πŸ“ Interview Prep

Python Interview Exercises

These exercises cover OOP design, built-in data structures, generators, and functional patterns β€” concepts commonly tested in Python interviews.

⏱️ 20 min read🎯 Interview PrepπŸ“… Updated 2026

Exercise 1 – Cache Decorator

Python
def cache(func):
    memo = {}
    def wrapper(*args):
        if args not in memo:
            memo[args] = func(*args)
        return memo[args]
    return wrapper

@cache
def expensive(n):
    print(f"Computing {n}...")
    return n * n

expensive(5)  # Computing 5... β†’ 25
expensive(5)  # from cache β†’ 25

Exercise 2 – Stack Class

Python
class Stack:
    def __init__(self):
        self._items = []

    def push(self, item): self._items.append(item)

    def pop(self):
        if not self._items:
            raise IndexError("Stack is empty")
        return self._items.pop()

    def peek(self):
        if not self._items:
            raise IndexError("Stack is empty")
        return self._items[-1]

    def __len__(self): return len(self._items)
    def __bool__(self): return bool(self._items)

s = Stack()
s.push(1); s.push(2); s.push(3)
print(s.peek())  # 3
print(s.pop())   # 3

Exercise 3 – Infinite Counter Generator

Python
def counter(start=0, step=1):
    n = start
    while True:
        yield n
        n += step

import itertools
evens = list(itertools.islice(counter(0, 2), 5))
print(evens)  # [0, 2, 4, 6, 8]

Exercise 4 – Timer Context Manager

Python
import time
from contextlib import contextmanager

@contextmanager
def timer(label=""):
    start = time.perf_counter()
    try:
        yield
    finally:
        elapsed = time.perf_counter() - start
        print(f"{label}: {elapsed:.4f}s")

with timer("List comp"):
    result = [x**2 for x in range(1_000_000)]

Exercise 5 – Flatten Nested List

Python
from collections.abc import Iterable

def flatten(iterable):
    for item in iterable:
        if isinstance(item, Iterable) and not isinstance(item, str):
            yield from flatten(item)
        else:
            yield item

nested = [1, [2, [3, 4]], [5, 6], 7]
print(list(flatten(nested)))  # [1, 2, 3, 4, 5, 6, 7]
Tip: In interviews: clarify requirements first, discuss time/space complexity, then handle edge cases before declaring done.

πŸ‹οΈ Practical Exercise

Warm up with focused drills:

  1. Write a memoizing cache decorator from scratch (then compare with functools.lru_cache).
  2. Implement a Stack class with push, pop, peek, and is_empty.
  3. Write a generator that yields an infinite counter.
  4. Flatten an arbitrarily nested list using recursion.

πŸ”₯ Challenge Exercise

Combine the building blocks: implement a Timer context manager, then use your Stack class and the flatten function together in a small program. Add type hints and a few tests for each component. For the cache decorator, support a configurable max size and demonstrate the speedup on a slow function. Bonus: re-implement the infinite counter both as a generator and as a class with __next__.

πŸ“‹ Summary

  • These exercises drill core Python skills used in interviews and real code.
  • A cache decorator demonstrates closures and decorators; functools.lru_cache does it for you.
  • A Stack class practices encapsulation and data-structure design.
  • Generators (yield) produce values lazily, including infinite sequences.
  • A Timer context manager applies the with protocol.
  • Flattening a nested list reinforces recursion.

Interview Questions on Python Coding Exercises

  • How do you write a decorator that caches function results?
  • How would you implement a stack in Python?
  • What is the difference between a generator and a regular function?
  • How do you build a context manager?
  • How do you flatten a nested list recursively?
  • When would you use functools.lru_cache?
  • How do these exercises map to real-world Python features?

FAQ

Why practice writing a cache decorator if lru_cache exists? +

Building one yourself cements your understanding of closures, decorators, and how memoization works. In real code you would usually reach for functools.lru_cache, but interviewers often ask you to implement the concept.

What is the difference between a generator and a regular function? +

A regular function returns once. A generator uses yield to produce a sequence of values lazily, pausing and resuming its state between calls β€” perfect for streams and infinite sequences without using extra memory.

How do I implement a stack in Python? +

A Python list already supports stack behavior with append (push) and pop. Wrapping it in a class with push, pop, peek, and is_empty gives a clean, explicit interface.

How do I flatten a deeply nested list? +

Recurse: iterate the list, and for each element, if it is itself a list, recurse into it and extend the result; otherwise append the value. This handles arbitrary nesting depth.