Syntax Hard¶
What does this code print?¶
print(0.1 + 0.2)
0.30.300000000000000040.300000000000000010.6
Answer¶
Floats are IEEE-754 binary approximations, so neither 0.1 nor 0.2 is
exact. Their sum rounds to a value slightly above 0.3, which repr
shows as 0.30000000000000004.
What is the output?¶
print(0.1 + 0.2 == 0.3)
TrueFalse0.3ValueError
Answer¶
Because 0.1 + 0.2 produces 0.30000000000000004 rather than exactly
0.3, the equality is False. This is why floats should be compared
with a tolerance, e.g. math.isclose.
What does this print?¶
a = 100
b = 100
print(a is b)
TrueFalse100TypeError
Answer¶
CPython pre-caches the small integers from -5 to 256, so both names
point at the same cached object and is is True. This is a CPython
implementation detail, not a language guarantee — never rely on is for
value comparison.
What does this code print?¶
x = 300
print(x is x + 0)
TrueFalse3000
Answer¶
300 is outside CPython's small-integer cache (-5 to 256), so
x + 0 computes a brand-new int object with the same value. Identity is
False even though the values are equal. This boundary is CPython-specific.
What is the output?¶
a = "hello"
b = "hello"
print(a is b)
TrueFalsehelloTypeError
Answer¶
CPython interns short string literals that look like identifiers, so both
names refer to the same interned object and is is True. This is an
implementation detail, not guaranteed by the language.
What does this print?¶
a = "hello"
b = "".join(["h", "e", "l", "l", "o"])
print(a is b)
TrueFalsehelloTypeError
Answer¶
A string built at runtime by join is not automatically interned, so it is
a different object from the interned literal a, even though the contents
are equal. is is False (== would be True).
What does this code print?¶
t = ([1, 2],)
try:
t[0] += [3]
except TypeError:
pass
print(t)
([1, 2],)([1, 2, 3],)TypeError([1, 2], [3])
Answer¶
+= on the list first extends it in place (mutating t[0]), then tries
to store the result back into the tuple, which raises TypeError. The
mutation already happened, so after swallowing the error the tuple holds
([1, 2, 3],).
What is the output?¶
class C:
x = 10
y = [x + i for i in range(3)]
print(C.y)
[10, 11, 12]NameError[0, 1, 2][10, 10, 10]
Answer¶
A comprehension runs in its own function scope, which cannot see names in the
enclosing class body. The iterable range(3) is evaluated in class scope,
but looking up x inside the comprehension fails with NameError.
What happens when you run this?¶
x := 5
print(x)
5SyntaxErrorNameErrorNone
Answer¶
The walrus operator := is not allowed as a bare, top-level statement; it
must appear inside a larger expression (often parenthesized). The module fails
to compile, so it raises SyntaxError and nothing prints.
What does this code print?¶
d = {True: 'a', 1: 'b', 1.0: 'c'}
print(d)
{True: 'a', 1: 'b', 1.0: 'c'}{True: 'c'}{True: 'a'}{1: 'c'}
Answer¶
True, 1 and 1.0 are equal and hash the same, so they are the same
dict key. Each assignment overwrites the value but keeps the first key
object, leaving {True: 'c'}.
What is the output?¶
print(-2 ** 2)
4-42-2
Answer¶
** has higher precedence than the unary minus, so this parses as
-(2 ** 2), which is -4. To square a negative you must write
(-2) ** 2.
What does this print?¶
gen = (x for x in range(3))
data = list(gen)
print(list(gen))
[0, 1, 2][][0, 1, 2, 0, 1, 2]ValueError
Answer¶
A generator can only be iterated once. The first list(gen) consumes it
fully, so by the second call it is exhausted and yields nothing, producing an
empty list [].
What does this code print?¶
a = [1, 2, 3, 4, 5]
a[::2] = [0, 0, 0]
print(a)
[0, 0, 0, 4, 5][0, 2, 0, 4, 0][0, 0, 0, 2, 4]ValueError
Answer¶
Extended slice assignment replaces the elements at indexes 0, 2 and 4 with the
three new values, leaving the odd indexes untouched, giving
[0, 2, 0, 4, 0]. The replacement length must match the slice length.
What is the output?¶
x = 10
def f():
print(x)
x = 5
f()
105UnboundLocalErrorNameError
Answer¶
Because x is assigned somewhere in f, it is treated as a local for the
whole function. The print(x) runs before that local is assigned, so it
raises UnboundLocalError rather than reading the global x.
What does this print?¶
print(0.1 + 0.2 + 0.3 == 0.3 + 0.2 + 0.1)
TrueFalse0.6ValueError
Answer¶
Floating-point addition is not associative: rounding happens at each step, and
different groupings accumulate different tiny errors. The two sums differ in
the last bit, so the comparison is False.
What does this code print?¶
print(2 ** 3 ** 2)
6451225618
Answer¶
Unlike most operators, ** is right-associative, so this is
2 ** (3 ** 2) = 2 ** 9 = 512. Left-associative evaluation would
have given (2 ** 3) ** 2 = 64.
What is the output?¶
lst = [10, 20]
print(lst[False], lst[True])
10 2020 10TypeErrorIndexError
Answer¶
Booleans are integers, so False and True act as the indexes 0 and
1. lst[False] is 10 and lst[True] is 20, printing
10 20.
What does this print?¶
s = "a" "b"
print(s)
aba b('a', 'b')SyntaxError
Answer¶
Adjacent string literals are concatenated at compile time, with no operator
needed. "a" "b" becomes the single string "ab".
What does this code print?¶
print(... is Ellipsis)
TrueFalseSyntaxErrorNameError
Answer¶
... is literal syntax for the built-in singleton Ellipsis, so they are
the same object and is is True.
What is the output?¶
x = [0, 0]
i = 0
x[i] = i = 1
print(x, i)
[0, 1] 1[1, 0] 1[1, 1] 1[1, 0] 0
Answer¶
The right-hand side 1 is evaluated once, then targets are assigned left to
right. First x[i] with the current i = 0 sets x[0] = 1; only then
does i become 1. So x is [1, 0] and i is 1.