Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected

How-tos

Python Interview Questions That Actually Get Asked — And How to Nail Them

Real Python interview questions that test your understanding of mutability, scoping, and exception handling — with code examples and the production bugs they cause.

June 2026 · 6 min read · 2 views · 0 hearts

Python Interview Questions That Actually Get Asked — And How to Nail Them

You've memorized the difference between __init__ and __new__. You can reverse a linked list in your sleep. Then the interviewer asks you to explain why a simple list comprehension broke their production code.

Interview prep can feel like studying for a trivia contest, but the best Python interview questions aren't trivia — they're tests of how you think under pressure. Here are the questions that keep appearing, explained with real code you'd actually write.

1. "What happens when you modify a list while iterating over it?"

This one trips up everyone at least once. The "official" answer is that it's unpredictable, but the real story is more interesting.

numbers = [1, 2, 3, 4, 5]
for i, n in enumerate(numbers):
    if n % 2 == 0:
        numbers.pop(i)
print(numbers)  # Output: [1, 3, 5] — wait, that worked?

It looked like it worked, but try with a slightly different list:

numbers = [1, 2, 3, 4, 5, 6]
for i, n in enumerate(numbers):
    if n % 2 == 0:
        numbers.pop(i)
print(numbers)  # Output: [1, 3, 5] — still wrong, but this time 6 survived?

The bug is subtle: when you pop an element, everything shifts left. The loop's index keeps advancing, so you skip elements. The solution? Never mutate a list while iterating. Instead, build a new list:

numbers = [n for n in numbers if n % 2 != 0]

But here's the real-world takeaway: this exact bug crashed a Django migration script I once debugged. The script processed user accounts and deleted inactive ones mid-loop. Half the accounts got skipped, leading to a 3 AM rollback.

2. "Explain mutable vs immutable default arguments"

The classic "gotcha" question that actually matters every single day:

def add_item(item, basket=[]):
    basket.append(item)
    return basket

print(add_item("apple"))  # ['apple']
print(add_item("banana"))  # ['apple', 'banana'] — wait, what?

The default list [] is created once when the function is defined, not each time you call it. Every call shares the same list object.

The fix is well-known:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

But here's the real-world reason this matters: I've seen a Flask API endpoint that used a mutable default to cache results. After ten requests, the cache had garbage from other users. The bug lived in production for months because it only showed up under concurrent load.

3. "What's the difference between is and ==?"

Intermediate devs know is checks identity, == checks equality. The interview question is usually about integer caching:

a = 256
b = 256
print(a is b)  # True — Python caches small integers

c = 257
d = 257
print(c is d)  # False — depends on implementation

The real-world lesson: never use is for value comparison. Use it only for singletons like None, True, or False. I once debugged a data pipeline where someone wrote if result is True: and it worked fine locally. On the production server (a different Python build), it silently failed for three weeks.

4. "How does Python handle variable scope?"

The question usually comes as: "What does this print?"

x = 10
def outer():
    x = 5
    def inner():
        x += 1
        return x
    return inner()

This throws UnboundLocalError because x += 1 makes x local to inner() — but it's referenced before assignment. The fix? nonlocal x.

The real-world angle: this bites you when refactoring. You start with a simple function, then add a nested helper to reduce duplication. Suddenly, variables you thought were "free" become local. The solution isn't memorizing scope rules — it's writing functions that don't need to mutate outer scope. If you're using nonlocal frequently, your design probably needs another look.

5. "How do you handle exceptions properly?"

The answer everyone gives: use try-except blocks. The answer that makes you sound like a senior: let exceptions propagate to the right level.

# Junior move
def process_file(path):
    try:
        with open(path) as f:
            return f.read()
    except:
        return None  # Bad — swallows all errors

# Senior move
def process_file(path):
    with open(path) as f:  # Let FileNotFoundError propagate
        return f.read()

# Handle it where you can act on it
def load_user_data(user_id):
    try:
        return process_file(f"/data/{user_id}.json")
    except FileNotFoundError:
        return {"error": "User not found"}

The real-world rule: catch exceptions at the level where you have enough context to handle them. Don't catch them in a library function where you can't decide what to do. I've seen codebases where every function had a try/except Exception — it turned deployment rollouts into guesswork because every bug became a silent None.

The Meta Lesson

The best Python interview questions aren't about syntax — they're about understanding how Python actually behaves under real conditions. When you explain these, don't just give the academic answer. Say: "I've seen this bug crash a production job at 2 AM, and here's why it happened."

That's the answer that gets you hired.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.