50 Python Practice Problems with Instant Answer Checking (Beginner to Advanced)
Fifty problems, each with a code editor and real tests. Write your solution, press Check, and see exactly which cases pass. Stuck? Hints reveal one at a time, and the solution unlocks once you have checked at least once. Your code and progress are saved in this browser.
They are grouped in three tiers. Beginner (1-20): strings, numbers, lists, dictionaries and your first error handling. Intermediate (21-35): generators, classic algorithms, regular expressions and a first class. Advanced (36-50): the interview staples (hash maps, sliding windows, dynamic programming, graphs) plus decorators, context managers, dataclasses and pandas.
Beginner Problems (1-20)
Strings, numbers, lists and dictionaries. If you are new to Python, go in order. If not, use them as a warm-up and move fast.
Problem 1: FizzBuzz
Write fizzbuzz(n) that returns a list of strings for the numbers 1 to n: "Fizz" for multiples of 3, "Buzz" for multiples of 5, "FizzBuzz" for multiples of both, and the number itself (as a string) otherwise.
fizzbuzz(5) -> ["1", "2", "Fizz", "4", "Buzz"]Problem 2: Reverse the Words
Write reverse_words(sentence) that returns the words in reverse order, separated by single spaces. Extra spaces anywhere in the input should not matter.
reverse_words("hello big world") -> "world big hello"Problem 3: Count the Vowels
Write count_vowels(text) that returns how many vowels (a, e, i, o, u) the text contains, ignoring case.
count_vowels("Hello World") -> 3Problem 4: Palindrome Check
Write is_palindrome(text) that returns True if the text reads the same forwards and backwards, ignoring case, spaces and punctuation.
is_palindrome("A man, a plan, a canal: Panama") -> TrueProblem 5: Sum of Digits
Write digit_sum(n) that returns the sum of the digits of the integer n. It must work for negative numbers too (ignore the minus sign).
digit_sum(1234) -> 10
digit_sum(-58) -> 13Problem 6: Largest Number Without max()
Write largest(numbers) that returns the largest number in the list without using `max()`. For an empty list return None.
largest([3, 9, 2]) -> 9
largest([]) -> NoneProblem 7: Remove Duplicates, Keep the Order
Write dedupe(items) that returns a new list without duplicates, keeping the first occurrence of each item in its original position.
dedupe([3, 1, 3, 2, 1]) -> [3, 1, 2]Problem 8: Second Largest Value
Write second_largest(numbers) that returns the second largest distinct value. If there is no such value (fewer than two distinct numbers), return None.
second_largest([4, 1, 4, 3]) -> 3
second_largest([7, 7]) -> NoneProblem 9: Most Common Character
Write most_common_char(text) that returns the character that appears most often, ignoring spaces and case. If there is a tie, return the one that appears first in the text.
most_common_char("Mississippi") -> "i"Problem 10: Are They Anagrams?
Write is_anagram(a, b) that returns True if the two strings use exactly the same letters the same number of times, ignoring case and spaces.
is_anagram("Listen", "Silent") -> TrueProblem 11: Factorial, With a Proper Error
Write factorial(n) that returns n! using a loop (no math.factorial). factorial(0) is 1. For a negative n, raise a `ValueError`.
factorial(5) -> 120
factorial(-1) -> ValueErrorProblem 12: Is It Prime?
Write is_prime(n) that returns True if n is a prime number. Numbers below 2 are not prime. Only test divisors up to the square root of n.
Problem 13: Letter Grade
Write letter_grade(score) for a score from 0 to 100: 90 and above is "A", 80+ "B", 70+ "C", 60+ "D", below 60 "F". A score outside 0-100 must raise `ValueError`.
Problem 14: Title Case Without .title()
Write title_case(text) that capitalises the first letter of every word and lower-cases the rest, without using str.title() or str.capitalize(). Words are separated by single spaces.
title_case("hELLO wORLD") -> "Hello World"Problem 15: Common Elements
Write common(a, b) that returns the items found in both lists, in the order they appear in a, without duplicates.
common([1, 2, 3, 2, 4], [4, 2, 9]) -> [2, 4]Problem 16: Flatten a List of Lists
Write flatten(rows) that turns a list of lists into one list, using a list comprehension.
flatten([[1, 2], [3], [], [4, 5]]) -> [1, 2, 3, 4, 5]Problem 17: Merge Two Inventories
Two shops store stock as dictionaries of item -> count. Write merge_inventory(a, b) that returns a new dictionary with the counts added together. Do not change the inputs.
merge_inventory({"apple": 3, "pear": 1}, {"apple": 2, "fig": 5})
-> {"apple": 5, "pear": 1, "fig": 5}Problem 18: Invert a Dictionary
Write invert(d) that swaps keys and values. Several keys can share a value, so each value maps to a list of keys, in their original order.
invert({"ann": "red", "bob": "blue", "cy": "red"})
-> {"red": ["ann", "cy"], "blue": ["bob"]}Problem 19: Password Strength Check
Write password_problems(pw) that returns a list of the rules the password breaks, in this order:
1. "too short" if it has fewer than 8 characters
2. "no digit"
3. "no uppercase"
4. "no lowercase"
A strong password returns [].
Problem 20: Average of Messy Input
Data from a form arrives as strings, and some are junk. Write safe_average(values) that converts each value to a float, skips anything that cannot be converted, and returns the average rounded to 2 decimals. If nothing is valid, return None.
safe_average(["4", "x", "5.5", ""]) -> 4.75Intermediate Problems (21-35)
Generators, the classic algorithms every programmer should be able to write from memory, regular expressions, and your first class with real rules.
Problem 21: Fibonacci Generator
Write a generator fibonacci() that yields the Fibonacci numbers forever: 0, 1, 1, 2, 3, 5, ... The tests take as many as they need with itertools.islice.
Problem 22: Sieve of Eratosthenes
Write primes_up_to(n) that returns all primes up to and including n using the Sieve of Eratosthenes: start with everything marked prime, then cross out the multiples of each prime.
Problem 23: Caesar Cipher
Write caesar(text, shift) that shifts every letter by shift places, wrapping around the alphabet. Keep the case, leave everything that is not a letter unchanged, and allow negative shifts (which decode).
caesar("Hello, World!", 3) -> "Khoor, Zruog!"Problem 24: Top Words in a Text
Write top_words(text, n) that returns the n most common words as (word, count) tuples. Ignore case and punctuation; a word is a run of letters (and apostrophes). Ties keep the order of first appearance.
top_words("The cat and the hat. The END!", 2) -> [("the", 3), ("cat", 1)]Problem 25: Group the Anagrams
Write group_anagrams(words) that groups words that are anagrams of each other. Return a list of groups; groups appear in the order their first word appears, and words keep their original order inside each group.
group_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"])
-> [["eat", "tea", "ate"], ["tan", "nat"], ["bat"]]Problem 26: Balanced Brackets
Write is_balanced(s) that returns True if every (, [ and { is closed by the matching bracket in the right order. Other characters are ignored.
is_balanced("{[()()]}") -> True
is_balanced("([)]") -> FalseProblem 27: Run-Length Encoding
Write rle(text) that compresses runs of the same character into the character followed by its count.
rle("aaabccdddd") -> "a3b1c2d4"Problem 28: Binary Search
Write binary_search(items, target) for a sorted list. Return the index of target, or -1 if it is not there. Do not use .index() or the bisect module.
Problem 29: Merge Two Sorted Lists
Write merge_sorted(a, b) that merges two already-sorted lists into one sorted list in a single pass. Do not call sort() or sorted().
Problem 30: Rotate a List
Write rotate(items, k) that rotates the list to the right by k places and returns a new list. k can be larger than the list.
rotate([1, 2, 3, 4, 5], 2) -> [4, 5, 1, 2, 3]Problem 31: Deep Flatten
Write deep_flatten(data) that flattens lists nested to any depth into one flat list.
deep_flatten([1, [2, [3, [4]], 5]]) -> [1, 2, 3, 4, 5]Problem 32: Roman Numerals
Write to_roman(n) that converts an integer from 1 to 3999 into Roman numerals, including the subtractive forms like IV (4), IX (9), XL (40) and CM (900).
Problem 33: Longest Common Prefix
Write common_prefix(words) that returns the longest prefix shared by every word in the list (an empty string if there is none, or if the list is empty).
common_prefix(["flower", "flow", "flight"]) -> "fl"Problem 34: Parse a Log Line With Regex
Server logs look like 2026-10-02 14:03:55 [ERROR] Disk almost full. Write parse_log(line) that returns a dict with "date", "time", "level" and "message", or None if the line does not match. Levels are upper-case words.
{"date": "2026-10-02", "time": "14:03:55", "level": "ERROR", "message": "Disk almost full"}Problem 35: A Bank Account Class
Write a class BankAccount:
BankAccount(owner, balance=0)deposit(amount) and withdraw(amount). Both raise ValueError for amounts of 0 or less, and withdraw raises ValueError if there is not enough money.balance propertyhistory is a list of ("deposit", amount) / ("withdraw", amount) tuples for successful operationsAdvanced Problems (36-50)
The interview staples (hash maps, sliding windows, dynamic programming, graphs), then the Python features that separate fluent code from working code: decorators, context managers, dataclasses and pandas.
Problem 36: Two Sum
Write two_sum(nums, target) that returns the indexes (i, j) with i < j of the two numbers that add up to target, or None if there are none. Do it in one pass (O(n)), not with two nested loops.
two_sum([2, 7, 11, 15], 9) -> (0, 1)Problem 37: Longest Substring Without Repeats
Write longest_unique(s) that returns the length of the longest substring with no repeated characters.
longest_unique("abcabcbb") -> 3 ("abc")
longest_unique("pwwkew") -> 3 ("wke")Problem 38: Merge Overlapping Intervals
Meetings are [start, end] pairs in any order. Write merge_intervals(intervals) that merges every overlapping (or touching) pair and returns the result sorted by start.
merge_intervals([[8, 10], [1, 3], [2, 6], [15, 18]])
-> [[1, 6], [8, 10], [15, 18]]Problem 39: Top K Frequent Elements
Write top_k(nums, k) that returns the k most frequent values, most frequent first. Ties go to the value that appears first in nums.
top_k([1, 1, 1, 2, 2, 3], 2) -> [1, 2]Problem 40: Maximum Subarray (Kadane)
Write max_subarray(nums) that returns the largest sum of any non-empty run of consecutive numbers, in O(n).
max_subarray([-2, 1, -3, 4, -1, 2, 1, -5, 4]) -> 6 ([4, -1, 2, 1])Problem 41: Coin Change (Dynamic Programming)
Write min_coins(coins, amount) that returns the fewest coins that add up to amount (each coin can be used any number of times), or -1 if it is impossible.
min_coins([1, 2, 5], 11) -> 3 (5 + 5 + 1)Problem 42: Longest Increasing Subsequence
Write lis_length(nums) that returns the length of the longest strictly increasing subsequence (the items do not need to be next to each other).
lis_length([10, 9, 2, 5, 3, 7, 101, 18]) -> 4 (2, 3, 7, 18)Problem 43: Shortest Path in a Graph (BFS)
A graph is a dict mapping each node to a list of neighbours. Write shortest_path(graph, start, goal) that returns the shortest path as a list of nodes, or None if goal cannot be reached. Explore neighbours in the order they are listed.
Problem 44: LRU Cache
Write a class LRUCache(capacity) with get(key) (returns the value, or -1 if missing) and put(key, value). When it is full, put evicts the least recently used key. Reading a key with get counts as using it. Both operations must be O(1).
Problem 45: Trie for Autocomplete
Write a class Trie with insert(word), search(word) (True only for whole words that were inserted) and starts_with(prefix), which returns a sorted list of all inserted words that begin with prefix.
Problem 46: Write a Memoize Decorator
Write a decorator memoize that caches a function's results by its positional arguments, so repeated calls return instantly. The decorated function must keep its original __name__. (Do not use functools.lru_cache or functools.cache.)
Problem 47: A Retry Decorator With Arguments
Write retry(times, exceptions=(Exception,)), a decorator factory. The decorated function is called up to times times; if it raises one of exceptions, try again. If the last attempt still fails, re-raise that error. Other exception types must not be retried.
@retry(times=3, exceptions=(ConnectionError,))
def fetch(): ...Problem 48: A Context Manager That Cleans Up
Write a context manager temporarily(obj, name, value) that sets the attribute obj.name = value inside a with block and always restores the original value afterwards, even if the block raises an error.
with temporarily(settings, "debug", True):
... # settings.debug is True here
# settings.debug is back to what it wasProblem 49: Revenue by Region With pandas
Each row of a sales DataFrame has region, price and qty. Write revenue_by_region(df) that returns a Series of total revenue (price * qty) per region, sorted from highest to lowest and rounded to 2 decimals. Do not modify df.
Problem 50: Leaderboard With a Dataclass
Create a dataclass Player with name: str and score: int. Then write leaderboard(players) that returns the names ranked by score (highest first), with ties ordered alphabetically by name.
What to Do Next
Each solved problem has a Save to GitHub button: it adds your solution to your own python-practice repository, with a progress table and a badge for your GitHub profile. Then test yourself under exam conditions with the section quizzes and earn a certificate, or follow the Python roadmap for the topics you found hardest.