11 Python Practice Problems for Beginners

11 Python Practice Problems for Beginners Featured Image

As someone who writes a lot about Python, I find these sort of a list posts to be a great way of compiling some of my work—especially if helps others. Today, we’ll go through a list of 11 Python practice problems for beginners.

Table of Contents

Why Practicing Is Important

When it comes to learning to code, nothing is more important than getting hands-on experience. Sure, the fundamentals are important, but the end goal should be to turn those theoretical skills into tangible programs. To do that, you need to solve a large variety of problems in your chosen domain.

Of course, when you’re a beginner, it’s tough to know where to start. After all, most programming courses only teach the mechanics of programming (i.e., if statements, loops, etc.). What they struggle to teach are higher levels of thinking beyond memorization and comprehension.

In fact, in education, we often refer to Bloom’s Taxonomy when it comes to learning. This is a simple model that gives us a way to think about different levels of mastery. In this taxonomy, there are 6 levels of cognitive processing organized from least sophisticated to most sophisticated:

  1. Remember: pull computing information from your memory
  2. Understand: make sense of computing discussions
  3. Apply: use algorithms in the appropriate situations
  4. Analyze: draw connections between related algorithms and programs
  5. Evaluate: judge an algorithm or program
  6. Create: generate new algorithms or programs

For a beginner, I would expect you to be floating in the first two stages. Perhaps you are familiar with some of the common programming mechanisms, but you’re struggling to decide when to use them. That’s okay! That’s why I recommend trying your hand at some practice problems.

Always Solve and Reflect

Coding is hard! Unfortunately, that means coding can also be extremely frustrating. My advice would be to come to terms with that frustration sooner rather than later. In other words, when you complete practice problems, make sure you solve them before you look up the solution. There are a couple reasons why I recommend this.

Delayed Feedback Can Improve Learning

The literature shows that regular feedback is important. However, getting feedback too soon (e.g., immediately after providing an answer) can disrupt the learning processOpens in a new tab.. According to the article linked, the reason for this is likely curiosity driven. In other words, if we want to know the answer and we’re stuck waiting for it, we might focus more attention on the solution.

I personally think that delayed feedback is more effective because it forces us to reflect on our solution in the meantime. This reflection process is a form of metacognition, and it’s an important part of learning. For example, we might try prompting ourselves by asking “how do we know our solution is correct?”

My theory stems from a couple of examples.

One example I always think of is that sometimes students will use an IDE when they first learn to code. There is nothing wrong with this, but it can hinder the learning process. If a student sees a red squiggly line every time there’s an error, there’s a good chance that they’ll just modify the line until it goes away. This is a trial & error approach that’s demonstrated in the literature (Jemmali et al. 2020Opens in a new tab.). If, however, students are forced to read cryptic error messages, there is more thought that has to go into solving the error. (Disclaimer: I’m not advocating for bad error messages. I’m just pointing out how immediate feedback might hinder learning.)

Another example that comes to mind for me is automated testing. When students are provided with tests for their code, they’re handed the keys to an immediate feedback system. As a result, they’re more likely to modify their code at random (e.g., a +1 here and a -1 there) to get the tests to pass than to critically think about why their solution doesn’t work.

Obviously, in both cases, there’s a certain level of sophistication required to know how to modify the code given the immediate feedback. However, I sometimes think this is teaching the wrong sort of skills; students become more reactive than proactive. Rather than asking “how can I solve this problem?”, students might ask “what do I need to change to get this to work?”

At the end of the day, however, I don’t think there is a right or a wrong way to approach learning. That said, it may help you learn better if you can resist the urge to rely on tools that provide immediate feedback (e.g., HackerRank, tutorials, etc.).

Delayed Feedback Offsets Cognitive Biases

One thing I learned in grad school was that it was very easy to convince myself that I knew something until I had to prove it. I don’t know exactly what the name of this cognitive bias is, but it bit many times in my computer science courses. I thought that if I just looked at solutions to various problems that I would know how to solve those problems if they came up on an exam; turns out that was a lie.

I suppose my experience very closely mirrors Bloom’s taxonomy. If I only memorized or understood an algorithm, that doesn’t mean I would be able to apply it in the appropriate context—nor does that mean I could modify it or adapt it to new contexts.

This happened to me quite a lot in my algorithms course. I would aggressively try to memorize the various dynamic programming algorithms because I never truly mastered the concept. When a problem came up on the exam, I was typically unable to connect the algorithms that I had memorized to the problem in front of me.

The moral of the story is that had I been provided some practice problems, I might have been able to perform better on the exam. However, the professor for this course never really tried to get us beyond basic understanding. And since I didn’t understand dynamic programming well enough to write my own practice problems, I was more or less stuck.

Fortunately, I’ll be spending the rest of this article providing some practice problems for you to get better at Python!

Practice Problems

In this section, I’ll share with you several problems you can try to solve on your own. These problems were inspired by my two main Python series: How to Python and Roll Your Own Python.

I took special care to select problems that I felt were most appropriate for beginners, and I even made sure to describe what types of mechanisms are emphasized in each problem. In other words, if you are specifically looking for practice practice problems for loops, look out for the “iteration” topic.

Finally, each problem is followed by a link to the solution. Take care not to peek at the solution until you’ve given your best shot.

Computing Exponents

One thing that helps beginners migrate into the world of programming is to provide context relevant problems. One context that we almost universally share is arithmetic. For example, any time we need to go make a purchase, we need to be able to total the cost of various items and compare that total with the amount of money we have on hand.

Unfortunately, arithmetic is often too straightforward in programming contexts because it’s natively provided through operators. That said, more complex tasks like computing exponents often are not (with the exception of Python). As a result, you either have to reach for a library, or you have to roll your own function.

That’s what makes problems like this so great for beginners. After all, you likely already know the algorithm for computing an exponent by hand. The challenge here becomes converting that algorithm to code.

Another reason I really like this problem is because it’s not as trivial as it initially appears. For example, you might already have an idea of how you would compute 28, but what if you needed to calculate something like 34.5 or 9-3. This different edge cases allow you to think about the problem in many different ways which should keep you occupied for awhile.

Computing Min/Max Values

Another interesting practice problem for Python beginners is this idea of computing minimum and maximum values. Since this is an offshoot of arithmetic, folks will likely be comfortable with comparing values in this way. After all, if you’re offered a bigger paycheck at work, you’ll likely take it. Can you convert your decision making process into code?

Sometimes computing minimum and maximum is done between a pair of values, and other times this is done on a collection of values. For beginners, I’d recommend starting small. Given a function that takes a pair of values (a & b), can you figure out which value is the smallest and/or biggest? How does the code change if you’re presented with a third value? What about a list of values?

This is a great challenge because it forces you to grapple with branching. Depending on how you choose to scale this problem, it can also encompass other data structures such as lists and trees.

Converting Lowercase to Uppercase

In our minds, we have a mapping between lowercase and uppercase characters. In programming, this is a bit less straightforward. That’s what makes it a great practice problem. Can you take what you know about the English language and turn it into code?

I particularly like this problem because there are a lot of ways present the problem while there are many different ways to solve those problems. For example, you could think about a function that takes in a letter and converts it to uppercase. Alternatively, you might think about how you would capitalize just the first letter of a string or all the letters in the string.

Regardless of how you choose to experiment with this problem, you’ll need to figure out how to convert between lowercase and uppercase letters. Even this problem has many different solutions: some based on arithmetic with others based on data structures. Hell, how do you even know the letter you’re looking at is lowercase?

Solving this conversion problem is certain to introduce you to the complexity of strings. Also, you might pick up a few skills along the way.

Swapping Variables

Another seemingly trivial task is swapping values between variables. I particularly like this problem because has varying levels of challenge. Upon first glance, it might seem like a simple idea: what if I assign the value of one variable to the other and vice versa? Very quickly, you’ll realize this doesn’t work, so what’s the alternative?

Once you get this working, you can start thinking about ways where the solution won’t hold up. For example, will your solution work in the context of swapping variables in a list? How about if you’re swapping objects?

Also, it’s sometimes helpful to think about contexts where this swapping skill might be useful. For instance, if you’re trying to sort a list in place, you’ll need to know how to swap the values around. Similarly, your minimum and maximum solution from above might be able to take advantage of you swapping mechanism.

By the time you have the hang of it, I recommend taking a peek at what Python has to offer in terms of making your life easier.

Removing Duplicates from a List

Perhaps the hardest challenge in this list for a beginner would be to try removing duplicates from a list. After all, this is useful you want to show a list of all the unique values in a list. As it turns out, this isn’t a trivial challenge—though there are ways to do it quickly.

Personally, I like this probably because it seems trivial at first. For example, you might grab an item from the list and scan for duplicates, repeating until you’ve checked every item. There’s is a great start and perhaps the way you might do it by hand, but what if there was a better way?

As you get better at programming, you’ll learn that there are ways to solve problems that save you a ton of thinking. This is one of those problems because writing the nested loops to check every pair of elements can be tricky to write. If you find a way to maybe count up all the duplicates before you remove them, you’ll have an easier solution to write. That said, if you don’t have much data structures experience, there are ways to solve this “by hand.”

If you’re feeling particularly, think about all the different types of data your list can hold. How does your solution change if your list contains strings, for instance?

Splitting a String by Whitespace

In general, I think any task involving string manipulation is a good task for a beginner. The more you do it, the more you realize just how complicated strings are. Also, it’s pretty great loop practice!

One challenge worth giving a go is splitting a string by whitespace. Basically, this means covering a string into a list of words by spaces. For example, here’s what you might expect:

sentence = "how are you?"
split_sentence = ["how", "are", "you"]

Like many of the practice problems in this list, splitting a string by whitespace is a seemingly trivial problem with hidden bumps along the way. Once you get the code working for a sentence like the one above, start thinking about what might happen if you try splitting a string the has a line break in it? What about a string with multiple spaces between words?

Not only is this task great looping practice, but you’ll also get a greater appreciation for the complexity of strings. Also, there are tons of ways to solve this problem, so try your hand at a few different solutions.

Computing Absolute Value

For this next practice problem, we’re going to revisit our love for arithmetic. This time, we’re going to take a look at a common math operation known as absolute value. If you’re familiar with this operation, then you know that it ensures a value is reported as greater than or equal to zero (aka nonnegative).

Implementing absolute value in code forces you to think about what it takes to convert negative numbers to positive ones. For example, if you were provided with a value, how do you tell if it’s negative? If it’s negative, how do you make it positive?

I like this problem as a beginner puzzle because it gets you thinking about ways to approach arithmetic from a programming lens. Also, you’re sure to get a chance to practice your branching.

When you figure out how to do it yourself, be thankful that Python has it implemented for you in the abs() function.

Merging Dictionaries

One skill that you should pick up early in Python is the use of dictionaries. In general, they’re really useful data structures that allow you to store more nuanced mappings akin to JavaScript objects.

That said, learning how to use them is only the tip of the iceberg. Once you’ve figured that out, other sort of challenges emerge. For example, what happens if you have two dictionaries that you’d like to merge?

For this challenge, you’ll become intimately comfortable with the dictionary data structure. Depending on how you go about the merging task, you might learn how to loop over dictionaries in the process. Alternatively, you might gain some familiarity with the various dictionary methods. Overall, I encourage you to try a few different approaches to get the full breadth of ways to work with a dictionary.

If you’re feeling adventurous, there are ways to merge dictionaries that take advantage of one of my favorite features in Python: comprehensions. For now though, this task should give you a bit more practice with navigating dictionaries.

Converting Pairs of Lists into Dictionaries

Since we’re on the topic of dictionaries, another common task that’s great practice for beginners is converting various data structures into other data structures. For example, you might have a pair of lists that serve as a mapping. In other words, the item in the first slot of the first list maps to the item in the first slot of the second list. If you iterate over both lists at the same time, you can look at each pair of values.

Of course, it’s likely that a better way to pair these values would be to use a nested list or even a dictionary. In the latter case, would you be able to convert two lists into a dictionary?

As it turns out, there are mechanisms for doing this, but the mapping process is a great exercise for anyone looking to build up a dictionary by hand. If done correctly, you’ll get some good practice with looping over pairs of lists. After that, you can take a look at some easier ways to get the job done.

Inverting Dictionaries

Yet another great task to try with dictionaries is inverting them. In other words, make every key a value and every value a key. If it helps, think of this task like flipping our lists from above. Instead of looking at list one then list two, look at list two and then list one.

As it turns out, there aren’t many easy ways to do this, and like many problems in this list, there are always caveats. As a result, if you manage to get a solution, I recommend trying it on a dictionary that has duplicate values. Does your solution still work? How would you change it if it doesn’t?

There are also other hiccups to begin thinking about. For instance, all values need to be hashable. What does that even mean? How do you test for this?

In general, as you try solving these various practice problems, think about ways you could make your solutions faster or more robust. This is always a great way to get better at programming.

Combining Elements of Two Lists

The last practice problem I have for you today is another list manipulation task. Rather than converting two lists into a dictionary, another think you might be interested in is merging two lists together.

Naturally, there are a lot of ways to do this. In my specific context, I was imagining a pair of lists containing numbers. Then, you can pairwise add those values until you have a single list containing the sums.

Another way this task might take form is combining two lists end-to-end, so the final list is the size of both lists put together. Alternatively, you could try some form of merging task where you mix in the min/max solution from above by creating a list that only contains the min/max of the pairs.

As you can imagine, there are a lot of ways to combine two lists. The more problems you can come up with and solve, the better prepared you’ll be to manipulate lists.

Next Steps

At the beginning of this article, I mentioned Bloom’s Taxonomy and how it can help us think about the different stages of mastery. At this point in your journey, you’re probably just beginning to apply what you’ve learned in different contexts. That’s awesome! Keep up the good work.

At a certain point, however, you might want to take your learning to the next level. In other words, instead of writing solutions to problems, you might want to try something more challenging. For example, you might try writing multiple solutions to the same problem and then comparing your solutions in terms of pros and cons. Similarly, you might try looking at my solutions with a critical lens. In other words, how could you improve them?

If it helps, I can provide you with a bit of an analogy. I’m a musician, and I’ve been told various ways to get better in the past. The obvious advice I always got was to practice, but no one tells you how to practice—at least until I was in college.

Then, I remember one of my professors telling me to try playing my music in all 12 keys. There were a few benefits to this. First, music generally is not available in all 12 keys (though that’s changing), so there’s a transposition process that you have to go through. Second, once you have the piece transposed, you have to grapple with a new key. The consequence of this is that you get more practice with your scales as well as your range.

Similar sorts of advice that I used to receive included things like transcribing a recording. The idea being that you can work on your ear by trying to convert the sound of a song to its written form. For serious musicians, this seems to be a pretty common practice—I suppose because it’s cheaper than paying for the sheet music. Also, if you’re strategic about whose music you’re transcribing, you can get a feel for their style.

Unfortunately, I’m not entirely sure how these examples translate back to coding mastery, but the moral of story is that you might have to get a bit creative in your practice. I know a lot of folks recommend finding existing programs that you can try to replicate. This is usually a bit more straightforward in the web development world because websites are literally everywhere, but there are definitely options in other realms as well (see: game development).

Regardless of how you choose to move forward, take care of yourself! Learning to code is a marathon, not a sprint. You’ll want to give yourself plenty of time to process your learning and not be too hard on yourself when you make mistakes. We all do!

At any rate, thanks again for taking the time to check out this article. If you’re into this type of thing, feel free to check out ways you can get involved here. For instance, we have a Discord server that we’re slowly building up. We also have a Patreon and a Newsletter. Any bit of support is awesome! Otherwise, take care.

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Code Posts