Python Output Quiz: Can You Predict What This Code Prints?
"Predict the output" is the single most common way interviews and CS exams probe whether you actually understand a language. All 12 snippets below run for real, and each hides a Python gotcha that makes even veterans pause. Work out the result in your head, then check.
0 / 12 answered
Q1
Call this function twice. What does the second print show?
def add(x, lst=[]):
lst.append(x)
return lst
print(add(1))
print(add(2))Q2
Two lists with identical contents — what do == and is give?
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b, a is b)Q3
Build a 2D grid with list multiplication, then change one cell.
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)Q4
Build lambdas in a loop, then call them all. What prints?
funcs = [lambda: i for i in range(3)]
print([f() for f in funcs])Q5
Use += on a list that lives inside a tuple. What happens?
t = ([1, 2],)
try:
t[0] += [3]
except TypeError:
pass
print(t)Q6
Floor division and true division — how do negatives work?
print(7 // 2, -7 // 2, 7 / 2)Q7
String * and + together — which binds first?
print("1" + "2" * 3)Q8
Do and / or return True/False?
print(0 or "hello")
print("" and "world")
print(2 or 3)Q9
Set dedup — and using both True and 1 as dict keys?
s = {1, 2, 2, 3, 3, 3}
d = {True: 'a', 1: 'b'}
print(len(s), len(d), d[1])Q10
What does this float equality check return?
print(0.1 + 0.2 == 0.3)Q11
Do out-of-range slices and indices raise errors?
lst = [1, 2, 3]
print(lst[-1], lst[1:99], lst[99:])Q12
A function prints an outer variable, then assigns to it. What happens?
x = 10
def f():
print(x)
x = 20
try:
f()
except UnboundLocalError:
print('error')Answer all 12 questions to see your result 👆
Eight places people trip
- Mutable default arg
- The [] in def f(x, lst=[]) is created once and shared across calls. Default to None, build inside.
- is vs ==
- == compares value, is compares identity. Use == for equality; reserve is for None checks.
- Reference, not copy
- [[0]*3]*3 makes three rows share one list; list * n copies references. Use a comprehension for independent copies.
- Late-binding closures
- A lambda's loop variable is looked up at call time, so all end up at the final value. Snapshot with lambda i=i: i.
- // floors
- -7 // 2 = -4 (toward -∞), not truncated -3. / always returns a float.
- and/or return operands
- They return a value, not True/False. That's how x = a or default works.
- Floats aren't ==
- 0.1+0.2 != 0.3. Compare with math.isclose or abs-difference under a threshold.
- Slices don't overflow
- An out-of-range index raises IndexError; an out-of-range slice clamps and returns quietly.
Why is 'predict the output' worth practicing?
| Code | What many expect | Actual output |
|---|---|---|
| add(1); add(2) (default lst=[]) | [1] and [2] | [1] and [1, 2] (shared list) |
| [[0]*3]*3, change one cell | one cell changes | whole column changes (one reference) |
| [lambda: i for i in range(3)] | [0, 1, 2] | [2, 2, 2] (late binding) |
| -7 // 2 | -3 (truncated) | -4 (floored) |
| 0.1 + 0.2 == 0.3 | True | False (float error) |
"Predict the output of this code" is the single most common style of question in coding interviews, CS exams, and practice sites — because it doesn't test whether you memorized an API. It tests whether you actually understand how the language runs: is a variable a reference or a copy? When does a closure evaluate? When is a default argument created? Get these right and you'll write far fewer bugs.
All 12 snippets above run for real, covering Python's most classic 'I thought… but it wasn't' traps: mutable default arguments, shared references, late-binding closures, float equality, scope rules. Each hides a principle that transfers straight into day-to-day coding.
These aren't Python 'design flaws' — they're natural consequences of its object model and evaluation rules. Once you view a variable as a label stuck onto an object (not a box holding a value), most of the behavior becomes obvious. That's the real skill this trains: moving from 'remember the answer' to 'derive the answer.'
Whether you're prepping for a coding interview, studying for a CS or IT course, or just starting Python and want solid foundations — treating 'predict the output' as regular practice is one of the fastest ways to go from 'can use it' to 'truly get it.'
Want to build that underlying understanding systematically? PurrLearn is turning programming, AI, and thinking into plain-language, quiz-first lessons — instant explanations, free to start.
FAQ
Is this quiz about rote memorization?
The opposite. Every question rests on a derivable rule (shared references, late binding, floor division…). Understand the rule and you can predict the output of code you've never seen — instead of memorizing answers. That's what makes this more valuable than drilling syntax.
What's the correct way to write a default-list argument?
Default to None and build inside: `def f(x, lst=None):\n if lst is None: lst = []`. Every call then gets a fresh list, with no cross-call sharing. Most linters warn on `lst=[]`.
When exactly should I use is vs ==?
Use == for value equality, always. Reserve `is` for identity — the common legitimate case is `x is None` / `x is not None`, since None is a singleton. Don't use is to compare numbers or strings; that hits caching implementation details.
Why can't I compare floats with ==?
Floats are stored in finite binary, and decimals like 0.1 aren't exactly representable, so arithmetic accumulates tiny errors (0.1+0.2 gives 0.30000000000000004). Compare with `math.isclose(a, b)` or check `abs(a-b) < 1e-9`.
Do these gotchas exist in other languages?
Some do, some are Python-specific. 'Reference not copy' and 'floats are imprecise' are near-universal; 'mutable default args' and 'late-binding loop closures' are classic Python (and some dynamic languages); JavaScript has its own set (var hoisting, == coercion, this binding). Understanding a language's traps is really understanding its evaluation model.