Python interview questions

16 programming language interview questions on Python, each with the correct answer and a full explanation.

What does this print?
def add(x, xs=[]):
    xs.append(x)
    return xs

add(1)
print(add(2))
Show answer

Answer

[1, 2]
Default values are evaluated once, when the def runs, so every call without xs shares one list. The usual fix is xs=None and creating the list inside.

Source: Python reference: Compound statements, Python programming FAQ

What does this print?
fs = [lambda: i for i in range(3)]
print([f() for f in fs])
Show answer

Answer

[2, 2, 2]
Closures look up i when called, not when created, and by then the loop has left i at 2. The loop stops at 2, so it is never 3. Bind it with lambda i=i: i.

Source: Python programming FAQ

What does this print?
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)
Show answer

Answer

[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
Multiplying the outer list copies the reference three times, so all rows are the same list. Build rows with [[0] * 3 for _ in range(3)].

Source: Python programming FAQ

What does this print?
nums = [1, 2, 2, 3]
for n in nums:
    if n == 2:
        nums.remove(n)
print(nums)
Show answer

Answer

[1, 2, 3]
Removing shifts later items left while the loop index keeps advancing, so the second 2 is skipped. Lists raise no error for this, unlike dicts. Build a new list instead.

Source: Python reference: Compound statements

What does this print?
a = [1, 2]
b = [1, 2]
print(a == b, a is b)
Show answer

Answer

True False
== compares values, is compares identity. Two list literals build two separate objects.

Source: Python reference: Data model

In Python 3.7 and later, what does this print?
d = {}
d["b"] = 1
d["a"] = 2
d["b"] = 3
print(list(d))
Show answer

Answer

['b', 'a']
Dicts keep insertion order, and updating an existing key does not move it. Ordering by key would need sorted(d).

Source: Python reference: Data model

What does this print?
a = [[1], [2]]
b = a.copy()
b[0].append(9)
b.append([3])
print(a)
Show answer

Answer

[[1, 9], [2]]
copy() is shallow: b is a new outer list holding the same inner lists. Appending to b leaves a alone, mutating b[0] does not. Use copy.deepcopy for nested data.

Source: Python programming FAQ

What does this print?
g = (x * x for x in range(3))
print(sum(g), sum(g))
Show answer

Answer

5 0
A generator can be consumed only once. The second sum gets an exhausted iterator and returns 0. Use a list if you need two passes.

Source: Python reference: Data model

After this runs, what is t?
t = ([1],)
try:
    t[0] += [2]
except TypeError:
    pass
Show answer

Answer

([1, 2],)
+= on a list extends it in place, then tries to store the result back into the tuple, which raises TypeError. The list was already changed, so t holds [1, 2].

Source: Python programming FAQ

What does this print?
print(-7 // 2, -7 % 2)
Show answer

Answer

-4 1
Python floors toward negative infinity, and % takes the sign of the divisor so that (a // b) * b + a % b == a. Java, Go, Kotlin and C truncate toward zero, which gives -3 and -1.

Source: Python programming FAQ

In Python, a class defines __eq__ but not __hash__. What happens on {P(1)}?
Show answer

Answer

TypeError: unhashable type
Defining __eq__ without __hash__ sets __hash__ to None, so instances cannot go in sets or be dict keys. Define __hash__ over the same fields that __eq__ compares.

Source: Python reference: Data model

What happens when inc() is called?
def make():
    count = 0
    def inc():
        count += 1
        return count
    return inc

inc = make()
inc()
Show answer

Answer

UnboundLocalError
Assigning count inside inc makes it local to inc, so count += 1 reads it before it is set. Declare nonlocal count to update the enclosing variable.

Source: Python programming FAQ

What does f() return?
def f():
    try:
        return 1
    finally:
        return 2
Show answer

Answer

2
A return in finally replaces the pending return, and also silently swallows exceptions. Python 3.14 emits a SyntaxWarning for this under PEP 765.

Source: Python reference: Compound statements, PEP 765: Disallow return, break and continue that exit a finally block

On the standard CPython build with the GIL, which speeds up a CPU bound pure Python function across 8 cores?
Show answer

Answer

ProcessPoolExecutor
The GIL lets one thread run Python bytecode at a time, so threads help with I/O, not CPU work. Processes each get their own interpreter. asyncio is single threaded. The free threaded build is a separate opt in.

Source: Python concurrent.futures documentation

In Python, inside an async function, a developer writes fetch() instead of await fetch(), where fetch is async def. What happens?
Show answer

Answer

A coroutine object is created and never runs, and Python warns it was never awaited
Calling an async function only creates a coroutine. Nothing runs until it is awaited or wrapped in a task, for example asyncio.create_task.

Source: Python asyncio: Coroutines and tasks

In Python, you build a large string from many pieces in a loop. Which approach is linear time and idiomatic?
Show answer

Answer

Collect the pieces in a list and call "".join(parts)
Strings are immutable, so repeated concatenation can copy the growing string each time, quadratic in the worst case. CPython sometimes optimizes +=, but that is an implementation detail.

Source: Python programming FAQ

These questions come from the Language Gotchas pack in Bertopia.

More programming language topics

Practise these on your commute