Robert Johns | 30 Oct, 2023

10 Common Python Mistakes in 2024 | Are You Making Them?

In this article, we share the 10 most common Python mistakes in 2024. But what are these common Python mistakes? And more importantly, are you making them?

Whether it’s a beginner mistake like forgetting colons or something more tricky like modifying a list while iterating over it, we dive into the rookie errors that you need to avoid!

We’ve also included detailed explanations for each of these common Python mistakes, along with code examples and best practices for avoiding them.

So whether you’re a beginner or a professional who’s making the transition to Python, read on to learn how to avoid these common Python mistakes!

How To Avoid Common Python Mistakes?

It goes without saying that the best way to avoid common Python mistakes is to develop a strong foundation in the language's basics. A great way to do that is to take a Python course

You should also be coding regularly by building Python projects while also reviewing best practices. 

Python IDE tools like linters are also a great way to identify potential issues before they manifest. If you see a squiggly line, it usually means something that you can learn from!

You could even use an AI coding assistant like GitHub Copilot or Amazon CodeWhisperer to ask for a sanity check within your codebase, and this might help you spot common mistakes. 

Speaking from experience, the only way to avoid Python mistakes is to make, understand, and remember how to avoid them.

That said, if you’re a Python beginner, try not to rely too heavily on tools like AI coding assistants in the early stages of your learning journey, as this is where you learn by doing!

It can be tempting to use something GitHub Copilot for help if you get stuck, but that might prevent you from reaping the benefits of that tricky but valuable phase of learning to code.

That way, you can integrate new knowledge into your own skill set, making you a better and more professional coder.

As time goes on

Let’s now dive into our list of the 10 most common Python mistakes to see whether you’re making any of them!

1. Assigning Mutable Dictionary Keys

In Python, dictionary keys must be immutable. This means you cannot use mutable types like lists as dictionary keys. If you try to do this, you'll see a TypeError

Why is that? It’s simple: dictionaries rely on hashing, requiring the keys to be constant values to ensure the hashing process is predictable.

But if you use mutable objects, these can be changed, meaning their hash values will be unpredictable, which in turn can compromise the integrity of the dictionary.

Let’s look at an example of this common Python mistake where we try to use a list as a dictionary key.

'''
Hackr.io: 10 Most Common Python Mistakes:
Assigning Mutable Dictionary Keys: Example
'''
my_lst = [1, 2, 3]
my_dct = {my_lst: 'value'}  # This will raise a TypeError

How can we fix this? Well, if you need to use a collection as a dictionary key, use a tuple! This is essentially an immutable list, making it an ideal replacement.

That said, it's essential to remember that the tuple's elements must also be immutable for the tuple to be hashable!

For example, if you had a tuple of lists, this would also be a problem.

'''
Hackr.io: 10 Most Common Python Mistakes:
Assigning Mutable Dictionary Keys: Solution
'''
my_tup = (1, 2, 3)
my_dct = {my_tup: 'value'}  # This is the correct approach

2. Forgetting Parentheses To Call Functions

In Python, functions are first-class objects. This means they can be passed around, assigned to variables, and more, just like you would with a string, an integer, a list, and so on. 

But when you reference a function without parentheses, you're referencing the function object, not invoking it.

This is a super common Python mistake for beginners, and it can lead to some unexpected behavior or bugs if you don’t understand the nuance.

Let’s take a look at a simple example to illustrate this. You can see that when we reference the function object and print, we get the memory location of the function object. 

'''
Hackr.io: 10 Most Common Python Mistakes:
Forgetting Parentheses To Call Functions: Example
'''
def greet():
  return 'Hello!'

message = greet 
# This assigns the function object to the variable, not its return value
print(message) 
# This will print something like: <function greet at 0x7f4c6d0d59d0>

But if you want to call a function and get its return value, use parentheses after the function's name, as shown in the solution below.

'''
Hackr.io: 10 Most Common Python Mistakes:
Forgetting Parentheses To Call Functions: Solution
'''
def greet():
  return 'Hello!'

message = greet() 
# This calls the function and assigns its return value to the variable
print(message) 
# This will print: Hello!

So, the main takeaway is that parentheses are crucial for differentiating between referencing a function and calling it. 

3. Forgetting Colons

In Python, colons signify the start of a new code block, whether that’s for functions, conditional statements, loops, or other control structures. 

Whether you’re a Python beginner or transitioning from another language, forgetting to add a colon can be a common Python mistake. 

But without the colon, Python doesn't recognize the subsequent indented block as belonging to the control structure, which causes a syntax error. No bueno!

Let’s take a look at some examples of this common Python mistake.

'''
Hackr.io: 10 Most Common Python Mistakes:
Forgetting Colons: Example
'''
def greet()   # Missing colon here
  return 'Hello!'

if True    # Missing colon here
  print('This is true!')

for i in range(3)   # Missing colon here
  print(i)

But thankfully, these are all super easy to fix, as shown in the code solution below.

'''
Hackr.io: 10 Most Common Python Mistakes:
Forgetting Colons: Solution
'''
def greet():  # Corrected with a colon
  return 'Hello!'

if True:  # Corrected with a colon
  print('This is true!')

for i in range(3):  # Corrected with a colon
  print(i)

As you can see, you just need to remember to add a colon at the end of the line before starting a new indented block.

4. Concatenating Strings & Integers

In Python, data types are strongly enforced, which means you can't concatenate strings and integers without explicitly converting one of the types. 

This is a common Python mistake for beginners who have come to rely on the versatility of Python’s dynamic typing, but it will always result in a TypeError.

Let’s take a look at a simple example to illustrate this mistake. You can see that we’ve tried to concatenate two string objects with an integer.

On the surface, this seems fine, as we just want to create a new string object, but we’ll always see a TypeError with this approach. 

'''
Hackr.io: 10 Most Common Python Mistakes:
Concatenating Strings And Integers: Example
'''
age = 25
message = 'I am ' + age + ' years old.'  # This will raise a TypeError

Fortunately, this is an easy Python mistake to fix, as shown in the solution below, where we’ve included two approaches.

Let’s start with the typecasting of the integer variable, as this converts the integer into a string, allowing us to concatenate without errors.

The second, sometimes more convenient approach is using a formatted string literal, or more succinctly, an f-string. 

Here, we can avoid concatenation altogether by adding the integer variable directly into our string output. We just need to use curly brackets as placeholders.

This is definitely one of those Python concepts I wish I knew earlier!

'''
Hackr.io: 10 Most Common Python Mistakes:
Concatenating Strings And Integers: Solution
'''
age = 25

# Using str() to convert the integer
message_1 = 'I am ' + str(age) + ' years old.'
print(message_1)  # Outputs: I am 25 years old.

# Using formatted string (f-string in Python 3.6+)
message_2 = f'I am {age} years old.'
print(message_2)  # Outputs: I am 25 years old.

The main takeaway is that you need to be cautious about data types when concatenating a string and an integer.

And if you do need to do this, use Python’s type conversion to combine strings and integers.

5. Confusing Equality & Assignment Operators

As two of the most widely used Python operators, newcomers to programming can find it easy to confuse the Python equality (==) and assignment (=) operators.

The issue here is that the equality operator checks whether two values are the same, but the assignment operator assigns a value to a variable. 

This means that one will return a Boolean value, and the other simply performs an assignment. 

You probably already know that! 

But it’s still really easy to misuse the assignment operator when you’re trying to check for equality. 

And if you do make that Python mistake, you’ll introduce hard-to-find bugs or syntax errors in your program, which is no fun! 

Let’s take a look at a simple example to see how this common Python mistake can find its way into your programming.

In this example, we want to check whether a variable is equal to an integer value, but we’ve used the assignment operator in the conditional statement.

'''
Hackr.io: 10 Most Common Python Mistakes:
Confusing Equality And Assignment Operators: Example
'''

x = 5
if x = 10:  # This will raise a syntax error
  print('x is 10')
else:
  print('x is not 10')

Fortunately, this Python mistake is super easy to fix, as we just need to swap out the assignment operator with the equality operator.

'''
Hackr.io: 10 Most Common Python Mistakes:
Confusing Equality And Assignment Operators: Solution
'''

x = 5

# Correctly using the equality operator
if x == 10:
  print('x is 10')
else:
  print('x is not 10')

6. Misunderstanding Variable Scopes

In Python, variable scopes are the regions of your code where a variable can be accessed or modified, and these tend to be either local or global. 

For Python beginners, especially those who have transitioned from languages with different scoping rules, understanding Python scopes can be tricky!

This becomes particularly clear when you use local and global variables with the same name, as local variables will overshadow global variables. 

Let’s look at a simple example to understand this Python mistake more clearly.

The purpose of this program is to modify the value of the global variable, and we’re going to do this with a user-defined function.

In this scenario, we’ve defined a global and local variable with the same name. This is always a bad idea, but let’s look at what happens next.

When we call the function, the print statement indicates that the variable value has been changed.

But when we use another print statement to check the value of the global variable, we can see that it has not been changed. What happened?

The issue here is that the function only modifies the local variable, and this ceases to exist after the function has exited.

This means we have not modified or accessed the global variable in any way. 

'''
Hackr.io: 10 Most Common Python Mistakes:
Misunderstanding Variable Scopes: Example
'''

x = 10  # Global variable

def change_x():
  x = 5  # Local variable with the same name
  print(f'Inside function: x = {x}')

change_x() # Output: Inside function: x = 5


print(f'Outside function: x = {x}') # Output: Outside function: x = 10

How can we fix this common Python mistake? Let’s take a look at a code solution with two different approaches.

Firstly, we can use the global keyword to access a global variable within a local function scope.

This allows us to modify the global variable with no problems.

The second approach involves passing the global variable as a function parameter, allowing us to modify the global variable within the function. 

We’ve also chosen to avoid using the same name for the local and global variables, as this is always a good practice!

'''
Hackr.io: 10 Most Common Python Mistakes:
Misunderstanding Variable Scopes: Solution
'''

# Solution 1: Using the 'global' keyword
x = 10

def change_global_x():
  global x
  x = 5
  print(f'Inside function (global x changed): x = {x}')
  # Output: Inside function (global x changed): x = 5

change_global_x()
print(f'Outside function: x = {x}') # Output: Outside function: x = 5


# Solution 2: Using different names to avoid confusion
y = 10

def change_local_y(local_y):
  local_y = 5
  print(f'Inside function: local_y = {local_y}')
  # Output: Inside function: local_y = 5
  return local_y

y = change_local_y(y)
print(f'Outside function: y = {y}') # Output: Outside function: y = 5

The key takeaway is to be cautious about variable names and their scopes, remembering that local variables inside functions will overshadow global variables that share the same name. 

When you need to modify a global variable inside a function, use the global keyword or pass in the variable as a function argument.

7. Modifying A List While Iterating Over It

This is one of the Python mistakes that you won’t realize is an issue until you run into it, but when you do, you’ll wish you’d avoided it!

The issue is that lists are mutable, so their size or order can change during iteration, making it tricky to keep track of the current element index or the items being evaluated.

Trust me, you want to avoid this problem!

When I was starting out with Python (which was a while ago now), I ran into this issue in the form of an IndexError, and I could not figure out what was happening.

To help you avoid this common Python mistake, let’s look at a simple example.

In this program, we simply want to remove all even-numbered elements from the list, and we’re doing this with a conditional check and the del statement.

On the surface, this approach of iterating through the list and removing the items directly seems fine, but it will generate an IndexError.

Why does this happen? Well, the list shrinks every time an element is removed, but the loop continues with the original indices from the original list length.

'''
Hackr.io: 10 Most Common Python Mistakes:
Modifying A List While Iterating Over It: Example
'''

numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
  if numbers[i] % 2 == 0:  # Remove even numbers
      del numbers[i]

How can we fix this Python mistake? The easiest way to avoid this issue is to iterate over a copy of the list, as shown in the solution below.

'''
Hackr.io: 10 Most Common Python Mistakes:
Modifying A List While Iterating Over It: Solution
'''

numbers = [1, 2, 3, 4, 5]
for num in numbers.copy():
  if num % 2 == 0:  # Remove even numbers
      numbers.remove(num)

print(numbers)  # Outputs: [1, 3, 5]

By creating a copy of the list, we can modify the original list without affecting the loop, allowing us to avoid that IndexError.

8. Using Loops Over List Comprehensions

List comprehensions might be one of my favorite features of the Python language, as they provide a concise and readable way to create lists

That said, a common Python mistake for newcomers to the language is to favor traditional loops when the same code can be hugely simplified with a list comprehension. 

There’s no doubt that loops are very versatile, and they allow us to handle more complex logic, but list comprehensions are more efficient and readable for straightforward operations.

Let’s look at a simple example to illustrate this point.

In this program, we want to create a list of squares from another list of numbers, and we’ve opted for a standard for loop to get the job done.

'''
Hackr.io: 10 Most Common Python Mistakes:
Using Loops Over List Comprehensions: Example
'''

numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
  squares.append(num * num)
print(squares)  # Outputs: [1, 4, 9, 16, 25]

Now, while the code is correct, it’s much more verbose than necessary, making it less Pythonic and thus, a mistake! 

For simple transformations like this, we can use a list comprehension to offer a more succinct and Pythonic solution, as shown below.

Look at how beautifully short and simple that code is! The very definition of Pythonic!

'''
Hackr.io: 10 Most Common Python Mistakes:
Using Loops Over List Comprehensions: Solution
'''

# Using a list comprehension
numbers = [1, 2, 3, 4, 5]
squares = [num ** 2 for num in numbers]
print(squares)  # Outputs: [1, 4, 9, 16, 25]

9. Not Using Docstrings

Documentation may not be the sexiest part of coding, but it’s a vital aspect of any codebase, regardless of its size.

Whether you’re brand new to coding and taking a Python course or an experienced pro that’s switching languages, docstrings are ideal for embedding descriptions within your code.

This makes it easier for other developers (and your future self) to understand how specific functions, classes, or modules operate.

But despite the obvious benefits, it’s actually more common than you’d think to come across code with zero documentation. 

This is a Python mistake you need to avoid! If not just for yourself, but for the benefit of your team!

Let’s look at a super simple example to hammer this point home. This is clearly a very simple function that calculates the area of a rectangle.

And while it seems straightforward, without a docstring, there's zero information about the expected parameter types, the return type, or any considerations the user should be aware of.

'''
Hackr.io: 10 Most Common Python Mistakes:
Not Using Docstrings: Example
'''

def rectangle_area(width, height):
  return width * height

Let’s look at a basic docstring that can simply and easily enhance this function's future use.

With the addition of a basic docstring, anyone reading the code immediately knows the function's purpose, its parameters, and its return type.

'''
Hackr.io: 10 Most Common Python Mistakes:
Not Using Docstrings: Solution
'''

def rectangle_area(width, height):
  """
  Calculates the area of a rectangle.

  Params:
  - width (float): The rectangle width.
  - height (float): The rectangle height.

  Returns:
  - float value: The area of the rectangle.
  """
  return width * height

The main lesson is to cultivate the habit of documenting your code with docstrings, especially for functions, classes, and modules. 

These enhance code readability and usability, making it easier to collaborate with others while also making future code maintenance easier. 

In professional environments, well-documented code is often a hallmark of quality.

10. Not Handling Exceptions

Let’s finish our list of common Python mistakes with exception handling.

To put it simply, exception handling is crucial for creating robust Python applications

If you don't anticipate and handle potential exceptions gracefully, your code can break. This is bad!

There really is no excuse for skipping this stage of the development process.

Think about it like this: if you don’t handle exceptions, you introduce the possibility of poor user experience, data corruption, and other problems.

If you want to be a professional coder, you need to spend the time to add exception handling to your programs.

Let’s look at a simple example to illustrate the issues that come with this common Python mistake.

In this program, the function raises a ZeroDivisionError when we attempt to divide by zero, potentially crashing the program.

'''
Hackr.io: 10 Most Common Python Mistakes:
Not Handling Exceptions: Example
'''

def divide_numbers(numerator, denominator):
  return numerator / denominator

result = divide_numbers(10, 0)
print(result) # Throws ZeroDivisionError

How can we avoid this? Let’s take a look at a solution that uses try-except blocks to catch potential exceptions and handle them gracefully.

This is a far more resilient approach, as by handling the exception, the function now provides meaningful feedback instead of abruptly terminating the program.

'''
Hackr.io: 10 Most Common Python Mistakes:
Not Handling Exceptions: Solution
'''

def divide_numbers(numerator, denominator):
  try:
      return numerator / denominator
  except ZeroDivisionError:
      return "Denominator cannot be zero."

result = divide_numbers(10, 0)
print(result)  # Outputs: Denominator cannot be zero.

It's super important to understand the potential exceptions your code might raise and handle them appropriately. 

And while it's tempting to use a broad except to catch all exceptions, it's typically better practice to catch and handle specific exceptions.

By doing this, you can avoid masking other unexpected issues that might be lurking. 

My advice: always strive to provide feedback or fallback solutions when handling exceptions to ensure your application remains user-friendly and reliable.

Common Python Mistakes: Wrapping Up

So there you have it, the 10 most common Python mistakes in 2024. How did you do? Were you making any of these Python mistakes in your own code?

Whether you’re new to Python or an experienced coder who’s making the switch to Python, learning how to avoid these Python mistakes can help you become a better coder.

That’s why we included detailed explanations for each of these Python mistakes, along with code examples and best practices to help you avoid them.

We hope you found this helpful! Have fun avoiding these common Python mistakes in the future!

Enjoyed learning about these Python mistakes and want to dive deeper? Check out:

Our Python Masterclass - Python with Dr. Johns

Frequently Asked Questions

1. What Are The Most Common Errors In Python?

If we’re talking about categories of error, these can be syntax errors or runtime exceptions. 

If we’re referring to mistakes, some of the most common are assigning mutable dictionary keys, forgetting parentheses to call functions, forgetting colons, concatenating strings and integers, confusing equality and assignment operators, and others we’ve covered above.

2. How Do You Find Mistakes In Python Code?

You can read error messages, utilize debugging tools, and use IDE tools such as linters and static code analyzers. You should also implement unit testing and code reviews to check your codebase for errors. You could also use an AI coding assistant if you have access to one.

By Robert Johns

Technical Editor for Hackr.io | 15+ Years in Python, Java, SQL, C++, C#, JavaScript, Ruby, PHP, .NET, MATLAB, HTML & CSS, and more... 10+ Years in Networking, Cloud, APIs, Linux | 5+ Years in Data Science | 2x PhDs in Structural & Blast Engineering

View all post by the author

Subscribe to our Newsletter for Articles, News, & Jobs.

Thanks for subscribing! Look out for our welcome email to verify your email and get our free newsletters.

Disclosure: Hackr.io is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.

In this article

Learn More

Please login to leave comments

Jim Markus

Doc strings are one of those things that seem unimportant when you first start out, then they become absolutely vital as your projects progress in complexity. Good advice.

5 months ago