Python Interview Drill and Checkpoint
55 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Fix the mistakes
The slips that cost marks in this module. Spot each one, then check the fix.
Real rounds mix topics: one program may use a default list, a lambda and a finally. This page drills them together. First learn to answer in three parts, then trace programs, then test yourself.
Answer in three parts: rule, example, catch
A model answer is a short reply in three parts: the rule in one sentence, a tiny example, and the catch that most people miss.
For "Why does my default list grow?": the rule is that defaults are evaluated once. The example is def f(x, items=[]). The catch is that None plus a new list inside is the fix.
def add(x, items=None): if items is None: items = [] items.append(x) return items
print(add(1), add(2))Example 1 · Mixed trace: names, defaults and finally
def record(event, log=[]): try: log.append(event) return len(log) finally: log.append("seen")
print(record("a"))print(record("b"))print(record.__defaults__[0])1 3 ['a', 'seen', 'b', 'seen']
What this code does
- The default list is shared.
return len(log)is computed first, thenfinallyaddsseen, so the first call returns 1 and leaves['a', 'seen']. - The second call sees that list: after
bit has three items and returns 3.__defaults__shows the shared list.
The example proves the rule in two lines. Say the catch last, because it is what shows you have met the bug in real code.
Predict the output before you run it
Most output questions combine two ideas from this module. Trace names first: which names point to one object? Then trace order: what runs, and when does finally or a lambda look up its value?
def build(n, acc=[]): acc.append(n) return acc
first = build(1)second = build(2)print(first is second, first)copy_list = first[:]first.append(3)print(copy_list)Example 2 · Copy and closure together
import copy
carts = [["pen"], ["book"]]shallow = carts.copy()deep = copy.deepcopy(carts)adders = [lambda c=cart: c.append("bag") for cart in carts]for add in adders: add()print(shallow)print(deep)[['pen', 'bag'], ['book', 'bag']] [['pen'], ['book']]
What this code does
- The lambdas bind each inner cart with a default, so each cart gets
bag.shallowshares the inner lists, so it shows them. deepwas copied before, so it is unchanged.
first and second are one list because of the default, so first is second is True and it holds [1, 2]. The slice is a separate list made before the append, so it stays [1, 2].
Spot the wrong answer
A wrong answer often sounds right. "Python is interpreted, so it has no compile step" skips bytecode. "Tuples are immutable, so everything inside is fixed" forgets that a list inside a tuple can change.
t = ([1], "a")t[0].append(2)print(t)try: t[1] = "b"except TypeError as err: print(err)Example 3 · Exception chain and cleanup
def load(text): try: return int(text) except ValueError as err: raise RuntimeError("bad input") from err finally: print("checked", text)
try: load("7") load("x")except RuntimeError as err: print(err, type(err.__cause__).__name__)checked 7 checked x bad input ValueError
What this code does
finallyprints for both calls, before the error leaves the function.RuntimeErroris raisedfromtheValueError, so the cause is kept.
The list inside the tuple changed, but the tuple still holds the same list. Assigning a new item raises TypeError. A strong answer states both facts.
Module quiz
Questions from the whole module. Your first answer is your score.
Problems
Graded easy to hard, using everything from this module.
Try each one yourself first. Use the hint if you get stuck. Mark it as done when it works.
Exercise 1· Easy
Print type(10 / 2).__name__, type(10 // 2).__name__ and type(2 ** 100).__name__ on three lines.
float int int
Exercise 2· Easy
Make a = [1, 2], b = a, c = list(a). Append 3 to a. Print b, c and a is b on three lines.
[1, 2, 3] [1, 2] True
Exercise 3· Easy
Write def clean_total(values) that adds up the numbers in a list of text values and ignores any that are not numbers. Print clean_total(["10", "x", "5", "", "7"]).
22
Exercise 4· Medium
Write def collect(item, bucket=None) that returns a list with the item added, creating a new list each time none is passed. Print collect(1), collect(2) and collect(3, [0]) on one line separated by | .
[1] | [2] | [0, 3]
Exercise 5· Medium
Given team = {"name": "A", "scores": [1, 2]}, make a deep copy, add 3 to the original scores and print the copy's scores, then the original's.
[1, 2] [1, 2, 3]
Exercise 6· Medium
Write def make_adders() returning a list of three functions where function i adds i to its argument (i from 0 to 2), without the late binding bug. Print the results of calling each on 10, as a list.
[10, 11, 12]
Exercise 7· Hard
Write def read_numbers(path) that returns the integers in a text file (one per line) as a list, skipping blank lines and lines that are not numbers, and returns [] if the file is missing. Using a temporary folder, write 4, x, a blank line, 6 to a file, then print read_numbers(<that file>) and read_numbers("missing.txt") on two lines.
[4, 6] []
Exercise 8· Hard
Write def tally(*words, **options) returning a dict with the count of each word. If options.get("lower") is true, lower-case the words first. Print tally("Pen", "pen", "Book", lower=True) and tally("Pen", "pen") on two lines.
{'pen': 2, 'book': 1}
{'Pen': 1, 'pen': 1}Interview questions
Questions interviewers ask on this topic.
What's next
You finished the preview of Core Python Questions
Python Programming has 21 sections, 110 modules and 609 lessons. An account opens every lesson and saves your progress.
Finish up
Mark complete & continue
Next: Classes, Instances, self and Attributes