HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
75 Topics
Chapter•390 Minutes

Complete Python Progressive Master Question Bank

75 progressive Python interview questions covering foundations, data structures, object-oriented concepts, memory mechanics, decorators, concurrency, and advanced language internals.

Q1: What is Python and how does its execution flow differ from compiled languages?

Python is a high-level, dynamically typed, interpreted programming language. Source code (.py) is first compiled into intermediate bytecode (.pyc). The Python Virtual Machine (PVM) then interprets this bytecode line-by-line into machine code at runtime.

Inspecting Python Bytecode
import dis

def add(a, b):
    return a + b

dis.dis(add) # Disassembles bytecode instructions
💡 The dis module exposes the raw PVM bytecode instructions produced for Python functions.
Key Takeaways
  • Compilation to Bytecode (.pyc) occurs automatically prior to PVM interpretation.
  • Dynamic typing resolves variable types at runtime rather than compile time.
Knowledge Check

What component in Python directly executes bytecode (.pyc) files?

Q2: What are the key operational differences between Lists and Tuples?

Lists are mutable sequence structures ([]), allocating extra memory over-allocation for dynamic resizing. Tuples are immutable sequence structures (()), occupying lower fixed memory footprint, faster allocation speeds, and supporting usage as dictionary keys.

Key Takeaways
  • Lists = Mutable, higher memory overhead.
  • Tuples = Immutable, lower memory, hashable (can be dict keys).
Knowledge Check

Can a tuple containing a list element be used as a key inside a Python Dictionary?

Q3: How do Dictionaries and Sets achieve O(1) average lookup times?

Python dictionaries and sets are backed by Hash Tables. Key hashes are computed via hash(key). In Python 3.6+, dictionaries use a compact array layout (an index array + a dense entries array), preserving insertion order while maintaining $O(1)$ key lookup and deletion.

Key Takeaways
  • Uses hash tables for $O(1)$ average lookups.
  • Python 3.6+ dicts preserve insertion order while reducing memory by ~20-25%.
Knowledge Check

What is the average time complexity for searching an element in a Python Set?

Q4: Why are mutable default arguments (e.g. def fn(arg=[])) considered dangerous?

Default argument values are evaluated once when the function definition is executed at module import time, NOT on each function invocation. Passing mutable default arguments ([] or {}) causes all subsequent calls to mutate the exact same shared object instance.

Safe Default Argument Pattern
# ❌ DANGEROUS: Shared list reference across invocations
def append_to(element, target=[]):
    target.append(element)
    return target

# ✅ SAFE PATTERN: Re-instantiate mutable inside call
def safe_append(element, target=None):
    if target is None:
        target = []
    target.append(element)
    return target
💡 Re-assigning target = [] inside function scope creates fresh list allocations per call.
Key Takeaways
  • Default parameter objects bind at function definition time.
  • Use None as default placeholder and assign new mutables inside the body.
Knowledge Check

What is returned by append_to(1) followed by append_to(2) using the dangerous pattern above?

Q5: What is the difference between the 'is' operator and the '==' operator?

  • == Operator: Checks value equality (invokes __eq__()).
  • is Operator: Checks object identity (verifies if two variables reference the exact same memory address using id(a) == id(b)).
Key Takeaways
  • == tests equivalence of values.
  • is tests memory address identity.
Knowledge Check

What does [1, 2] == [1, 2] and [1, 2] is [1, 2] evaluate to?

Q6: What is the difference between copy.copy() and copy.deepcopy()?

  • Shallow Copy (copy.copy()): Creates a new container object, but populates it with references to child objects inside the original.
  • Deep Copy (copy.deepcopy()): Recursively duplicates the container AND all nested child objects, constructing completely independent object graphs.
Key Takeaways
  • Shallow copy duplicates top-level container only.
  • Deep copy duplicates container and all nested child object references recursively.
Knowledge Check

If you modify a nested list inside a shallow copied object, does the original object's nested list update?

Q7: How do *args and **kwargs function in Python signatures?

  • *args: Captures variable positional parameters as a Tuple.
  • **kwargs: Captures variable keyword parameters as a Dictionary. Allow passing arbitrary parameter lists to functions or forwarding arguments in wrapper functions.
Forwarding Arguments via Wrapper
def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with {args} and {kwargs}")
        return func(*args, **kwargs) # Unpacks parameters seamlessly
    return wrapper
💡 *args and **kwargs capture and forward arbitrary parameters to the target function.
Key Takeaways
  • *args collects positional arguments into a tuple.
  • **kwargs collects keyword arguments into a dictionary.
Knowledge Check

What type of data structure is *args stored as inside function scope?

Q8: What are List Comprehensions versus Generator Expressions?

  • List Comprehension ([x for x in data]): Evaluates the entire sequence eagerly, building a full list in heap memory.
  • Generator Expression ((x for x in data)): Evaluates elements lazily on-demand, returning an iterator with minimal $O(1)$ memory footprint.
Key Takeaways
  • List Comprehension = Eager evaluation ($O(N)$ memory). Generator Expression = Lazy iteration ($O(1)$ memory).
Knowledge Check

Which construct should be preferred when streaming 10 GB of log data line-by-line?

Q9: What are Lambda functions and what limitations do they enforce?

Lambda functions are small, anonymous single-line functions created via lambda params: expression. They automatically return expression results and are restricted to a single expression (no statements, assignments, or multiline loops allowed).

Key Takeaways
  • Single-expression inline functions.
  • Useful for short callbacks in map(), filter(), or sorted(key=...).
Knowledge Check

Can a lambda function contain explicit return statements or assignment operations in Python?

Q10: What is the LEGB Rule for Python scope resolution?

Python resolves variable names in strict sequential order:

  1. L (Local): Inside active function/lambda body.
  2. E (Enclosing / Nonlocal): In enclosing nested function scopes.
  3. G (Global): At module top-level.
  4. B (Built-in): Preloaded Python built-in names (len, range).
Key Takeaways
  • Scope resolution order: Local -> Enclosing -> Global -> Built-in.
  • Use global or nonlocal keywords to rebind variables in outer scopes.
Knowledge Check

Which keyword must be used inside a nested inner function to rebind a variable declared in its parent outer function scope?