Python MCQs multiple-choice questions with answers & explanations
All 22 Python quiz questions on one page. Pick an answer in your head, then open Show answer to check it and read why. Want a score and a timer? Take them as a quiz instead.
- 1.easy
What does this print?
def append_to(x, items=[]): items.append(x) return items append_to(1) print(append_to(2))- A
[2] - B
[2, 1] - C
[1, 2] - D
TypeError
Show answer
Answer: C (
[1, 2])The default list is created once, when
defruns, and is shared by every call that omitsitems. The first call leaves1in it, so the second call returns[1, 2]. The fix isitems=Noneand creating the list inside the function. - A
- 2.mid
What does this print?
funcs = [lambda: i * 10 for i in range(3)] print([f() for f in funcs])- A
[0, 10, 20] - B
[0, 0, 0] - C
NameError - D
[20, 20, 20]
Show answer
Answer: D (
[20, 20, 20])Closures capture the variable
i, not its value at creation time, and look it up when called. By then the loop has finished withi == 2, so every lambda returns20. Binding the value with a default argument,lambda i=i: i * 10, gives[0, 10, 20]. - A
- 3.mid
What happens when this runs?
count = 0 def increment(): count += 1 return count print(increment())- AIt prints
1 - BIt prints
0 - CIt raises
UnboundLocalError - DIt raises
SyntaxErrorat definition
Show answer
Answer: C (It raises
UnboundLocalError)count += 1is an assignment, so the compiler treatscountas local to the whole function. Reading it before it has a local value raisesUnboundLocalError. Declaringglobal countinside the function (or better, passing and returning the value) fixes it. - AIt prints
- 4.easy
What does this print?
def f(*args, **kwargs): print(type(args).__name__, type(kwargs).__name__) f(1, a=2)- A
list dict - B
tuple dict - C
tuple list - D
list list
Show answer
Answer: B (
tuple dict)*argsalways collects extra positional arguments into a tuple, and**kwargscollects extra keyword arguments into a dict. Neither is ever a list. - A
- 5.hard
What does this print?
data = [3, -1, 4] kept = [y for x in data if (y := x * 2) > 0] print(kept, y)- A
[6, 8] 8 - B
[6, 8] -2 - C
[6, 8] 4 - D
NameError
Show answer
Answer: A (
[6, 8] 8)An assignment expression inside a comprehension binds its name in the enclosing scope, so
yexists afterwards. It is reassigned on every iteration, and the last item4givesy = 8. The loop variablexitself does not leak. - A
- 6.mid
What does this print?
grid = [[0] * 3] * 3 grid[0][0] = 1 print(grid)- A
[[1, 0, 0], [1, 0, 0], [1, 0, 0]] - B
[[1, 0, 0], [0, 0, 0], [0, 0, 0]] - C
[[1, 1, 1], [0, 0, 0], [0, 0, 0]] - D
[[1, 1, 1], [1, 1, 1], [1, 1, 1]]
Show answer
Answer: A (
[[1, 0, 0], [1, 0, 0], [1, 0, 0]])Multiplying the outer list copies the reference to one inner list three times, so all three rows are the same object and the change shows up in each. Build independent rows with
[[0] * 3 for _ in range(3)]. - A
- 7.easy
What does this print?
print(type((1)), type((1,)))- A
<class 'tuple'> <class 'tuple'> - B
<class 'int'> <class 'int'> - C
<class 'int'> <class 'tuple'> - D
<class 'tuple'> <class 'int'>
Show answer
Answer: C (
<class 'int'> <class 'tuple'>)Parentheses alone only group an expression, so
(1)is just the int1. It is the comma that makes a tuple:(1,)or even1,is a one-element tuple. - A
- 8.hard
What does this print?
d = {True: "a", 1: "b", 1.0: "c"} print(d)- A
{True: 'a', 1: 'b', 1.0: 'c'} - B
{1.0: 'c'} - C
{True: 'a'} - D
{True: 'c'}
Show answer
Answer: D (
{True: 'c'})True == 1 == 1.0and they hash the same, so they are the same dict key. The first key object inserted (True) is kept, while each later assignment overwrites the value, leaving{True: 'c'}. - A
- 9.mid
What does this print?
import copy a = {"tags": ["x"], "n": 1} b = copy.copy(a) b["tags"].append("y") b["n"] = 2 print(a)- A
{'tags': ['x', 'y'], 'n': 1} - B
{'tags': ['x'], 'n': 1} - C
{'tags': ['x', 'y'], 'n': 2} - D
{'tags': ['x'], 'n': 2}
Show answer
Answer: A (
{'tags': ['x', 'y'], 'n': 1})A shallow copy creates a new dict whose values are the same objects. Appending mutates the shared list, so
asees'y', butb["n"] = 2only rebinds a key inb. Usecopy.deepcopyto make the nested list independent. - A
- 10.mid
What does this print?
a = [1, 2] b = a a += [3] c = a a = a + [4] print(b, c is b)- A
[1, 2] False - B
[1, 2, 3, 4] True - C
[1, 2, 3] False - D
[1, 2, 3] True
Show answer
Answer: D (
[1, 2, 3] True)On a list,
+=extends the existing object in place, sobsees3andcis that same list.a = a + [4]builds a new list and rebinds onlya, sobandcstill point to[1, 2, 3]. - A
- 11.easy
What does this print?
squares = (n * n for n in range(3)) print(sum(squares), sum(squares))- A
5 5 - B
5 0 - C
0 5 - D
TypeError
Show answer
Answer: B (
5 0)A generator expression is a single-pass iterator. The first
sumconsumes0 + 1 + 4 = 5, and the second finds it already exhausted, so it sums nothing and returns0. Use a list if you need to iterate more than once. - A
- 12.easy
What does this print?
first, *middle, last = "abcd" print(middle)- A
('b', 'c') - B
'bc' - C
['b', 'c'] - D
['a', 'b', 'c']
Show answer
Answer: C (
['b', 'c'])A starred target in an assignment always collects the leftover items into a list, whatever the type of the iterable being unpacked. Here
firstis'a',lastis'd', andmiddleis['b', 'c']. - A
- 13.easy
What does this print?
s = "python" print(s[::-2])- A
'pto' - B
'yhn' - C
'noht' - D
'nhy'
Show answer
Answer: D (
'nhy')With a negative step and no bounds, slicing starts from the last character and walks backwards:
n, skipo,h, skipt,y, skipp. So the result is'nhy';'pto'would bes[::2]. - A
- 14.mid
What does this print?
words = ["bb", "a", "ccc", "dd", "e"] print(sorted(words, key=len))- A
['a', 'e', 'bb', 'dd', 'ccc'] - B
['e', 'a', 'dd', 'bb', 'ccc'] - C
['a', 'e', 'dd', 'bb', 'ccc'] - D
['ccc', 'bb', 'dd', 'a', 'e']
Show answer
Answer: A (
['a', 'e', 'bb', 'dd', 'ccc'])Python's sort is stable: items with equal keys keep their original relative order.
'a'came before'e'and'bb'before'dd'in the input, so they stay that way within each length group. - A
- 15.easy
What does this print?
try: x = int("42") except ValueError: print("bad", end=" ") else: print("ok", end=" ") finally: print("done")- A
bad done - B
ok - C
bad ok done - D
ok done
Show answer
Answer: D (
ok done)int("42")succeeds, so theexceptblock is skipped and theelseblock runs, becauseelseruns only when thetryraised nothing.finallyruns in every case, givingok done. - A
- 16.mid
What does this print?
def f(): try: return "try" finally: print("finally", end=" ") print(f())- A
try - B
finally try - C
try finally - D
finally
Show answer
Answer: B (
finally try)The
returnvalue is computed, then thefinallyblock runs before the function actually returns, sofinallyis printed first. The caller then prints the returnedtry. (Areturninsidefinallywould override it, and 3.14 warns about that.) - A
- 17.hard
What does this print?
class A: def who(self): return "A" class B(A): def who(self): return "B" + super().who() class C(A): def who(self): return "C" + super().who() class D(B, C): def who(self): return "D" + super().who() print(D().who())- A
DBA - B
DCBA - C
DBACA - D
DBCA
Show answer
Answer: D (
DBCA)D's MRO isD, B, C, A, object.super()means the next class in the instance's MRO, soB'ssuper().who()callsC.who, notA.who, andAruns only once:DBCA. - A
- 18.hard
What happens when the last line runs?
class Point: def __init__(self, x): self.x = x def __eq__(self, other): return self.x == other.x print({Point(1)})- AA set containing one
Point - BA
TypeError: unhashable type - CAn empty
set()is printed - DAn
AttributeErroronother.x
Show answer
Answer: B (A
TypeError: unhashable type)Defining
__eq__without__hash__sets__hash__toNone, making instances unhashable, so they cannot go into a set or be dict keys. Python does this to protect the rule that equal objects must have equal hashes. Define__hash__over the same fields to fix it. - AA set containing one
- 19.mid
What does this print?
class Animal: @classmethod def create(cls): return cls() class Dog(Animal): pass print(type(Dog.create()).__name__)- A
Animal - B
type - C
Dog - D
TypeError
Show answer
Answer: C (
Dog)A classmethod receives the class it was called on as
cls. Called viaDog,clsisDog, socls()builds aDog. That is why classmethods are the idiomatic way to write alternative constructors that work for subclasses. - A
- 20.mid
What happens when this code runs?
from dataclasses import dataclass @dataclass class Cart: items: list = []- AIt works; all carts share one list
- BClass definition raises
ValueError - CIt raises
TypeErroron firstCart() - DIt works; each cart gets a fresh list
Show answer
Answer: B (Class definition raises
ValueError)@dataclassrejects mutable defaults likelist,dictandsetwith aValueErroras soon as the class is defined, precisely to prevent the shared-default bug. Useitems: list = field(default_factory=list). - 21.hard
What does this print?
RED = "red" def check(color): match color: case RED: return "red!" print(check("blue"))- A
red! - B
None - C
SyntaxError - D
NameError
Show answer
Answer: A (
red!)A bare name in a
caseis a capture pattern: it matches anything and binds the subject toRED, so"blue"matches. It is not compared to the constant; use a dotted name such asColor.REDfor that. (If anothercasefollowed, Python would reject it as unreachable.) - A
- 22.mid
On standard CPython (with the GIL), which option actually runs a CPU-bound pure-Python function in parallel across 8 cores?
- A
ThreadPoolExecutorwith 8 workers - B
ProcessPoolExecutorwith 8 workers - C
asyncio.gatherover 8 coroutines - DWrapping the function in
@lru_cache
Show answer
Answer: B (
ProcessPoolExecutorwith 8 workers)Separate processes each have their own interpreter and GIL, so they run truly in parallel. Threads take turns holding the GIL for pure-Python bytecode,
asynciois single-threaded, and caching only helps repeated identical calls. - A