Python Coding Challenges & Practice Test
A static, self-check practice test for Python 3 — predict-the-output questions and coding challenges with a complete answer key
Python Coding Challenges
This self-check practice test covers core Python 3 fundamentals: syntax, data types, control flow, functions, strings, lists, dictionaries, sets, comprehensions, and common algorithms. Work through Section A (multiple choice / predict-the-output) and Section B (coding challenges) on your own first. Each item is numbered so you can verify your work against the matching entry in the Answer Key & Solutions section at the bottom of the page. All snippets and solutions run correctly on Python 3.
Section A: Multiple Choice / Predict the Output
Read each snippet carefully and choose the correct result or concept. Answers A1–A10 are in the answer key.
A1. List mutability and aliasing
a = [1, 2, 3]
b = a
b.append(4)
print(a)
What does this print?
Options:
(a) [1, 2, 3] (b) [1, 2, 3, 4] (c) [4] (d) Error
A2. Slicing
s = "python"
print(s[1:4])
What is printed?
Options:
(a) "pyth" (b) "yth" (c) "ytho" (d) "yt"
A3. Negative-step slicing
s = "python"
print(s[::-1])
What is printed?
Options:
(a) "python" (b) "nohtyp" (c) "" (d) Error
A4. Mutable default argument pitfall
def add(x, items=[]):
items.append(x)
return items
print(add(1))
print(add(2))
What is printed across the two calls?
Options:
(a) [1] then [2] (b) [1] then [1, 2] (c) [1, 2] then [1, 2] (d) Error
A5. Truthiness
print(bool([]), bool([0]), bool(0), bool("0"))
What is printed?
Options:
(a) False True False True (b) True True False False (c) False False False False (d) False True False False
A6. Integer vs. true division
print(7 // 2, 7 / 2, 7 % 2)
What is printed?
Options:
(a) 3 3.5 1 (b) 3.5 3.5 1 (c) 3 3 1 (d) 4 3.5 1
A7. dict.get with a default
d = {"a": 1}
print(d.get("b", 0))
What is printed?
Options:
(a) None (b) 0 (c) KeyError (d) 1
A8. Set comprehension and uniqueness
nums = [1, 2, 2, 3, 3, 3]
print(len({x for x in nums}))
What is printed?
Options:
(a) 6 (b) 3 (c) 1 (d) Error
A9. Comprehension building a dict
print({x: x * x for x in range(3)})
What is printed?
Options:
(a) {0: 0, 1: 1, 2: 4} (b) {1: 1, 2: 4, 3: 9} (c) [0, 1, 4] (d) {0, 1, 4}
A10. Exception handling flow
try:
x = int("abc")
except ValueError:
x = -1
print(x)
What is printed?
Options:
(a) 0 (b) -1 (c) "abc" (d) The program crashes
Section B: Coding Challenges
Eight problems of increasing difficulty. Write your own solution first, then check against B1–B8 in the answer key.
FizzBuzz
Print the numbers from 1 to n. For multiples of 3 print "Fizz", for multiples of 5 print "Buzz", and for multiples of both print "FizzBuzz".
Example:
Input: n = 15
Output: 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
Reverse the words in a sentence
Given a sentence, return a new string with the order of the words reversed. Collapse runs of whitespace to single spaces.
Example:
Input: "the quick brown fox"
Output: "fox brown quick the"
Count word frequency with a dict
Given a string of words, return a dictionary mapping each word (case-insensitive) to the number of times it appears.
Example:
Input: "the cat the dog the bird"
Output: {'the': 3, 'cat': 1, 'dog': 1, 'bird': 1}
Check for a palindrome
Return True if a string is a palindrome, ignoring case and any non-alphanumeric characters.
Example:
Input: "A man, a plan, a canal: Panama"
Output: True
Two Sum
Given a list of integers and a target, return the indices of the two numbers that add up to the target. Assume exactly one solution exists.
Example:
Input: nums = [2, 7, 11, 15], target = 9
Output: [0, 1] # because nums[0] + nums[1] == 9
Flatten a nested list
Given a list that may contain nested lists to any depth, return a single flat list of all the values in order.
Example:
Input: [1, [2, [3, 4], 5], [6]]
Output: [1, 2, 3, 4, 5, 6]
Fibonacci sequence
Return a list of the first n Fibonacci numbers, starting from 0, 1. Aim for an efficient iterative solution.
Example:
Input: n = 8
Output: [0, 1, 1, 2, 3, 5, 8, 13]
A simple class: BankAccount
Write a BankAccount class with an initial balance, a deposit method, and a withdraw method that raises ValueError on insufficient funds. Expose the current balance.
Example:
acct = BankAccount(100)
acct.deposit(50)
acct.withdraw(30)
print(acct.balance) # 120
acct.withdraw(1000) # raises ValueError
Answer Key & Solutions
Section A answers with explanations, followed by full solutions for Section B
Section A — Answers
- A1: (b) [1, 2, 3, 4].
b = abinds another name to the same list object, so appending throughbmutates the objectaalso refers to. - A2: (b) "yth". Slicing
s[1:4]includes index 1 up to but not including index 4 — characters at positions 1, 2, 3. - A3: (b) "nohtyp". A step of
-1walks the string backwards, reversing it. - A4: (b) [1] then [1, 2]. The default list is created once when the function is defined and shared across calls, so it accumulates values.
- A5: (a) False True False True. Empty containers and
0are falsy; a non-empty list and a non-empty string (even"0") are truthy. - A6: (a) 3 3.5 1.
//is floor division,/is true (float) division, and%is the remainder. - A7: (b) 0.
dict.getreturns the supplied default when the key is missing instead of raisingKeyError. - A8: (b) 3. A set keeps only distinct values, so the duplicates collapse to {1, 2, 3}.
- A9: (a) {0: 0, 1: 1, 2: 4}. A dict comprehension maps each key to its square over
range(3). - A10: (b) -1.
int("abc")raisesValueError, which is caught and setsx = -1.
B1 — FizzBuzz
def fizzbuzz(n):
for i in range(1, n + 1):
if i % 15 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
Check i % 15 (3 and 5 together) before the individual checks. Runs in O(n) time.
B2 — Reverse the words
def reverse_words(sentence):
return " ".join(reversed(sentence.split()))
str.split() with no argument splits on any whitespace and drops empties; reversed reverses the word list and join rebuilds the string. O(n) in the length of the input.
B3 — Word frequency
def word_count(text):
counts = {}
for word in text.lower().split():
counts[word] = counts.get(word, 0) + 1
return counts
# Idiomatic alternative:
# from collections import Counter
# return dict(Counter(text.lower().split()))
dict.get(word, 0) avoids a separate "key exists" check. collections.Counter is the idiomatic standard-library tool. O(n) over the words.
B4 — Palindrome check
def is_palindrome(s):
cleaned = [c.lower() for c in s if c.isalnum()]
return cleaned == cleaned[::-1]
Keep only alphanumeric characters, lowercase them, then compare against the reverse. O(n) time and O(n) extra space.
B5 — Two Sum
def two_sum(nums, target):
seen = {} # value -> index
for i, n in enumerate(nums):
complement = target - n
if complement in seen:
return [seen[complement], i]
seen[n] = i
return None
A hash map lets you look up the needed complement in O(1), giving an overall O(n) single-pass solution instead of the O(n²) brute force.
B6 — Flatten a nested list
def flatten(items):
result = []
for item in items:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
Recursion handles arbitrary nesting depth: lists are flattened in place via extend, scalars are appended. O(n) in the total number of elements.
B7 — Fibonacci sequence
def fibonacci(n):
seq = []
a, b = 0, 1
for _ in range(n):
seq.append(a)
a, b = b, a + b
return seq
Tuple assignment a, b = b, a + b advances both values without a temporary variable. Iterative and O(n), avoiding the exponential cost of naive recursion.
B8 — BankAccount class
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("Deposit must be positive")
self.balance += amount
def withdraw(self, amount):
if amount > self.balance:
raise ValueError("Insufficient funds")
self.balance -= amount
__init__ sets the initial state; withdraw validates funds before mutating and raises ValueError when the request exceeds the balance. Each operation is O(1).
Related Resources
Continue practicing and deepen your skills
SQL Practice Test
Self-check SQL challenges covering joins, aggregation, and query writing with full solutions.
Start PracticingMachine Learning Practice Test
Test your understanding of core ML concepts, models, and evaluation with a complete answer key.
Start PracticingData Science Python Cheat Sheet
A quick reference for Python data-science workflows, NumPy, and pandas essentials.
View Cheat SheetPython for Data Analysis
A full course applying Python to real-world data analysis tasks, from basics to projects.
Explore CourseFrequently Asked Questions
Common questions about this Python practice test
All snippets and solutions are written for Python 3. Behaviors such as true division with /, print() as a function, and dict comprehensions reflect Python 3 semantics.
Attempt each question and challenge on your own first — ideally by predicting outputs in your head or running your own code — then scroll to the Answer Key & Solutions section and compare. The numbering (A1–A10, B1–B8) lets you check items individually.
No. The provided solutions are correct and idiomatic, but most problems have multiple valid approaches. As long as your solution produces the expected output and has reasonable complexity, it is acceptable.
Syntax, data types, control flow, functions, strings, lists, dictionaries, sets, comprehensions, exception handling, and common algorithms such as FizzBuzz, two-sum, palindrome checking, and Fibonacci.