Reading about Python builds vocabulary. Solving small drills builds fluency. The 30 exercises below cover the six core skill areas every Python beginner needs to develop muscle memory in: strings, numbers, lists, dictionaries, loops, and functions. Each one ships with a hint and a modern Python 3 worked solution, so you can stop staring at a blank screen and start typing. For the wider learning path these drills slot into, see our complete Python beginner guide.
Key Takeaways
Drills train one skill at a time and build syntax muscle memory; projects combine many skills and build judgment. Both matter, but skip the drills and you'll stall before the projects start working.
Per the Stack Overflow Developer Survey 2024, 49% of professional developers learned to code primarily through self-study, with daily drills as the most common starting tool (Stack Overflow, 2024).
Three to five focused drills per day, with 20-minute attempts before peeking at the solution, beats two-hour weekend marathons. The forgetting-curve research from Hermann Ebbinghaus underlies why spaced repetition works (overview of the forgetting curve).
Re-solve each exercise from a blank file 3 days later. That's when a solved problem turns into a remembered solution.
Move from drills to projects once roughly 80% of the 30 below feel obvious. Earlier and you'll fight your tools; later and you'll plateau.
30
curated drills across 6 skill areas
~15
minutes median per drill (first try)
3
days between solve and re-solve
80%
fluency threshold to start projects
How Do You Use This Exercise Set?
Pick one category per day and work through its five drills in order. The order inside each category goes from gentle to stretching, so the first exercise warms you up and the fifth one pushes a bit further than feels comfortable. Try the problem cold for up to 20 minutes before reading the hint, then for another 10 before opening the solution. After you read a solution, close the page and re-type it from a blank file. That single habit is what converts reading into knowing.
Drills are not projects. A drill trains one skill at a time, like list comprehensions or dictionary lookups, with a sharp definition of "done." A project combines many skills and builds judgment about how they fit together. You need both, and we cover the project side in our 25 Python projects for beginners. For drills specifically, muscle memory comes from quantity at a moderate difficulty, not from one heroic struggle.Time falls roughly in half on the second attempt, and again on the third. That's the drill payoff.
Which String Exercises Build Core Fluency? (5 Drills)
Strings are usually the gentlest place to start. Every exercise here can be done with built-in methods you've already met, so the focus is on chaining them cleanly rather than learning anything new.
1. Reverse a String Without Using Slicing
Given "hello", return "olleh", but without using the [::-1] trick.
Hint:reversed() returns an iterator; "".join() collects it back into a string.
Given "Education is the best investment", return 11.
Hint: a generator expression with sum() is one line.
def count_vowels(s: str) -> int:
return sum(1 for ch in s.lower() if ch in "aeiou")
assert count_vowels("Education is the best investment") == 11
3. Check Whether a Word Is a Palindrome
Given "A man a plan a canal Panama", return True; given "hello", return False.
Hint: strip non-alphanumeric characters and lowercase first, then compare with the reversed copy.
def is_palindrome(s: str) -> bool:
cleaned = "".join(ch.lower() for ch in s if ch.isalnum())
return cleaned == cleaned[::-1]
assert is_palindrome("A man a plan a canal Panama")
assert not is_palindrome("hello")
4. Find the Longest Word in a Sentence
Given "the quick brown fox jumps over a lazy dog", return "quick" (or "jumps" — both are length 5).
Hint:max() takes a key= argument.
def longest_word(sentence: str) -> str:
return max(sentence.split(), key=len)
assert longest_word("the quick brown fox jumps over a lazy dog") in {"quick", "jumps"}
5. Replace Every Space With an Underscore (Without .replace())
Given "convert me to snake case", return "convert_me_to_snake_case" without calling str.replace.
Hint: split on whitespace, then join with the replacement character.
def spaces_to_underscores(s: str) -> str:
return "_".join(s.split())
assert spaces_to_underscores("convert me to snake case") == "convert_me_to_snake_case"
Which Number and Math Drills Should You Master? (5 Drills)
Number drills exist to make for-loops and the modulo operator feel natural. None of them need math or numpy; the goal is fluent control flow.
6. Sum of Even Numbers From 1 to N
For n = 10, return 30 (the sum 2 + 4 + 6 + 8 + 10).
Hint:range(start, stop, step) takes a step argument.
For n = 5, return 120, using a plain loop instead of recursion.
Hint: initialize result = 1, then multiply through range(2, n + 1).
def factorial(n: int) -> int:
result = 1
for i in range(2, n + 1):
result *= i
return result
assert factorial(5) == 120
assert factorial(0) == 1
8. First N Terms of the Fibonacci Sequence
For n = 7, return [0, 1, 1, 2, 3, 5, 8].
Hint: two variables and tuple-unpacking: a, b = b, a + b.
def fibonacci(n: int) -> list[int]:
a, b = 0, 1
out = []
for _ in range(n):
out.append(a)
a, b = b, a + b
return out
assert fibonacci(7) == [0, 1, 1, 2, 3, 5, 8]
9. Check Whether a Number Is Prime
Return True for 7 and False for 9.
Hint: you only need to test divisors up to the square root of n.
def is_prime(n: int) -> bool:
if n < 2:
return False
return all(n % i != 0 for i in range(2, int(n ** 0.5) + 1))
assert is_prime(7)
assert not is_prime(9)
10. Round Currency Amounts to Two Decimals
For 19.995, return Decimal("20.00"), not 20.0. Floats accumulate rounding errors and break invoices.
Hint: use decimal.Decimal with ROUND_HALF_UP, not the built-in round().
Hint: a nested list comprehension reads as "for each sublist, for each item in it".
def flatten_one_level(nested: list[list]) -> list:
return [item for sub in nested for item in sub]
assert flatten_one_level([[1, 2], [3, 4], [5]]) == [1, 2, 3, 4, 5]
15. Group Consecutive Duplicates Into Run-Length Pairs
Given "aaabbc" as characters, return [("a", 3), ("b", 2), ("c", 1)].
Hint:itertools.groupby handles this without manual state.
from itertools import groupby
def run_length(items) -> list[tuple]:
return [(key, len(list(group))) for key, group in groupby(items)]
assert run_length("aaabbc") == [("a", 3), ("b", 2), ("c", 1)]
Which Dictionary Drills Show Up Most Often? (5 Drills)
Dictionaries appear in roughly every real-world Python script you'll write, so the drills here matter disproportionately. The collections module does the heavy lifting on three of them.
16. Count Word Frequency in a Paragraph
Given "the cat sat on the mat", return {"the": 2, "cat": 1, "sat": 1, "on": 1, "mat": 1}.
Hint:collections.Counter does exactly this.
from collections import Counter
def word_frequency(text: str) -> dict[str, int]:
return dict(Counter(text.lower().split()))
assert word_frequency("the cat sat on the mat") == {"the": 2, "cat": 1, "sat": 1, "on": 1, "mat": 1}
17. Merge Two Dictionaries With Summed Values
Given {"a": 2, "b": 3} and {"b": 1, "c": 4}, return {"a": 2, "b": 4, "c": 4}.
Hint:Counter objects add together with the + operator.
Which Loop and Control-Flow Drills Are Worth Practicing? (5 Drills)
Loops feel mechanical once they click, but the click takes a couple of weeks. These five drills are the ones that produce that click.
21. FizzBuzz (Classic Variant)
Print numbers 1 through 15: substitute "Fizz" for multiples of 3, "Buzz" for multiples of 5, and "FizzBuzz" for multiples of both.
Hint: build up a string conditionally; print the string or fall back to the number.
for n in range(1, 16):
out = ""
if n % 3 == 0:
out += "Fizz"
if n % 5 == 0:
out += "Buzz"
print(out or n)
22. Print a Multiplication Table
For n = 7, print "7 x 1 = 7" through "7 x 10 = 70".
Hint: f-strings inside a single for-loop.
def multiplication_table(n: int) -> None:
for i in range(1, 11):
print(f"{n} x {i} = {n * i}")
23. Build a Pyramid Pattern With Asterisks
For height = 4, print:
*
***
*****
*******
Hint: on row i (1-indexed), print height - i spaces and 2*i - 1 asterisks.
def pyramid(height: int) -> None:
for i in range(1, height + 1):
print(" " * (height - i) + "*" * (2 * i - 1))
pyramid(4)
24. Find the First Non-Repeating Character in a String
For "swiss", return "w". For "aabb", return None.
Hint: count first with Counter, then scan the original string in order.
from collections import Counter
def first_unique_char(s: str) -> str | None:
counts = Counter(s)
return next((ch for ch in s if counts[ch] == 1), None)
assert first_unique_char("swiss") == "w"
assert first_unique_char("aabb") is None
25. Simulate a Dice-Roll Game Until a Target Total
Roll a six-sided die repeatedly, summing the results until the running total hits or exceeds 50. Return the number of rolls used.
Hint:while loop plus random.randint(1, 6).
import random
def rolls_to_target(target: int) -> int:
total, rolls = 0, 0
while total < target:
total += random.randint(1, 6)
rolls += 1
return rolls
print(rolls_to_target(50)) # roughly 14-16
Which Function and Algorithm Drills Stretch You Further? (5 Drills)
The last five drills combine the earlier categories. None of them are hard in isolation, but the act of stitching together strings, loops, and dicts inside a single function is the actual goal.
26. Return Both the Average and the Median of a List
Three habits separate learners who finish the set from learners who quit halfway. None of them are surprising, and that's the point: the surprise is how few people actually do them.
Solve without looking, for up to 20 minutes. Stuck past that, read the hint, not the solution. Stuck for another 10, read the solution, close the page, and re-type it from a blank file. Reading code is not the same as writing it; your fingers learn syntax that your eyes only recognize. The first night you type out 30 solutions, you will feel slow. The second night you'll feel less slow, and by the seventh you'll start to feel something close to fluency.
Re-solve the same exercise 3 days later. This is the spaced-repetition habit, and it builds on the well-documented forgetting curve described by Ebbinghaus. A problem you solved on Monday and re-solved on Thursday turns into a problem you can solve forever. A problem you solved once on Monday lives for about a week in your head, then fades. The 3-day re-solve is the single highest-impact practice habit you can adopt.
Read your own solutions out loud, one week later. Open Monday's file on the following Monday and read it aloud, line by line. Either it makes sense (you've internalized the pattern) or it doesn't (you've forgotten and need another pass). This is faster than re-solving and tells you precisely where your gaps are. Pair it with the 10 common beginner mistakes checklist to catch any anti-patterns you're still typing.
When Should You Move From Exercises to Projects?
The cleanest rule of thumb: when roughly 80% of the 30 drills above feel obvious within their first 5 minutes, you've passed the syntax-fluency threshold. Below that, drills still give you the fastest skill-per-hour return. Above it, projects start to outpace drills because the new skill you need (combining patterns, handling messy real-world inputs) only shows up inside larger programs.
"Obvious" doesn't mean "instantly solved." It means you read the problem, your fingers know roughly which functions to reach for, and the work is execution rather than discovery. If half the drills still require Googling a method name, stay with drills for another week or two. For project ideas calibrated to that fluency level, jump to our 25 Python projects for beginners.
Where Can You Get More Python Exercises?
Four reliable, platform-neutral options to extend beyond the 30 above:
HackerRank Python Basics. Free, well-graded, gentle difficulty curve. The auto-judge is strict, which trains attention to edge cases.
LeetCode (Easy tag, Python language filter). Geared toward interview preparation, but the easies overlap heavily with what you'd see in a junior screen. Skip the mediums until you've finished at least 30 easies.
Exercism Python track. Free, with optional human code review. Pace is slower but the feedback quality on a submitted solution is the best of the four.
Python.org's official tutorial exercises. Tucked at the end of each chapter. Quietly excellent because they target exactly the concept just introduced (Python tutorial).
If you want auto-graded drills with instant feedback and a gamified progression that keeps you returning daily, CodeGym's Python track is built around the same loop. Every solution gets checked by an AI validator in seconds, and the AI mentor explains the failure when your code doesn't pass. We also cover the broader "learn Python through play" angle in our gamified Python practice spoke.
Run These Drills With Instant AI Feedback
CodeGym's Python track turns the exercises-and-feedback loop into 800+ practical tasks across 62 levels. The AI validator checks every submission in seconds; the AI mentor explains where you went wrong when stuck. First level is free, and the full track is on the pricing page.
Open the free Python track →
Should You Use AI Assistants on These Drills?
The short answer is: rarely on drills, sparingly on projects. The point of a drill is to build the neural pathway for one specific Python pattern, and asking ChatGPT to do it for you skips the exact training your brain needs. Save the AI for syntax lookups ("what's the signature of str.split?") and for explanations after you've struggled and want to understand what you missed. Once you move on to projects, AI assistants pay off more, because integrating five libraries is closer to research than to muscle-building.
Frequently Asked Questions
How many Python exercises should I do per day?
Three to five focused drills per day beats twenty rushed ones. Aim for 45-60 minutes of practice, alternating between solving fresh problems and re-solving older ones. Quality of focus during each attempt matters more than raw count, and short daily sessions outperform marathon weekend sessions because spaced repetition is how long-term memory forms.
Is it OK to look at the solution if I can't solve one?
Yes, but only after 20 minutes of honest attempts. Read the solution, close the page, then re-implement it from scratch without peeking. The act of typing the working code yourself is what trains your fingers. Tomorrow, solve the same exercise from a blank file, and you'll discover whether the lesson actually stuck.
Are LeetCode-style exercises useful for beginners?
LeetCode easies are useful once you can fluently write loops, functions, and dictionary lookups. Before that, they're discouraging and skip too many fundamentals. Start with drills like the 30 above to build syntax fluency, then graduate to LeetCode easies once you can solve them without consulting documentation. Junior interview prep (our Python interview Q&A spoke goes deeper) typically asks for easy-level proficiency only.
Should I time myself on Python exercises?
Not in your first three months. Speed comes from repetition, not from artificial pressure. Once you can solve an exercise correctly without help, then add a soft time cap on a re-solve as a fluency check. For interview prep specifically, time yourself only on the last two weeks before the screen, to build comfort with the format.
The Bottom Line: Drills Build Fluency, Then Projects Take Over
Thirty drills, three to five a day, with a 3-day re-solve loop, will move you from "I read Python" to "I write Python" inside a single month. The drills aren't the destination; they're the bridge that makes projects feel possible. Once 80% of these feel obvious, jump to the 25 Python projects for beginners, and for the full learning arc from first print to first paid role, start with our complete Python beginner guide
GO TO FULL VERSION