Top 10 Mistakes in Python and How to Avoid Them (With Examples)

Python is one of the most popular programming languages, known for its simplicity and flexibility. However, many developers (beginners and experienced alike) often make common mistakes that can lead to inefficient code, errors, and security risks.

In this article, we’ll go through the top 10 mistakes in Python, explain why they happen, and show how to fix them with real-world examples.

Let’s dive in! 🐍

1️⃣ Using Mutable Default Arguments in Functions

Bad Code (Mutating Default Arguments)

def add_item(item, item_list=[]):  
    item_list.append(item)  
    return item_list  

# Calling function multiple times  
print(add_item('apple'))  # ['apple']  
print(add_item('banana'))  # ['apple', 'banana'] ❌ Unexpected behavior

🔴 Issue: The default list is shared across multiple function calls, leading to unintended modifications.

Good Code (Using None as Default)

def add_item(item, item_list=None):  
    if item_list is None:  
        item_list = []  
    item_list.append(item)  
    return item_list  

print(add_item('apple'))  # ['apple']  
print(add_item('banana'))  # ['banana'] ✅ Correct behavior

Why is this better?
✔ Ensures that each function call gets a new list.

2️⃣ Modifying a List While Iterating Over It

Bad Code (Incorrect Deletion in a Loop)

numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)  # ❌ Modifying list during iteration

print(numbers)  # [1, 3, 5] (missed elements)

🔴 Issue: The loop skips elements because the list size is modified while iterating.

Good Code (Iterate Over a Copy)

numbers = [1, 2, 3, 4, 5]
numbers = [num for num in numbers if num % 2 != 0]  # ✅ List comprehension

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

Why is this better?
✔ Prevents iteration issues by creating a new list instead of modifying the original one.

3️⃣ Using is Instead of == for Comparisons

Bad Code (is Instead of ==)

a = "hello"
b = "hello"

print(a is b)  # True (sometimes), False (other times) ❌ Unreliable

🔴 Issue: is checks object identity, not value equality.

Good Code (Use == for Value Comparison)

a = "hello"
b = "hello"

print(a == b)  # ✅ True (always reliable)

Why is this better?
== compares values, ensuring consistent results.

4️⃣ Ignoring Exception Handling

Bad Code (No Exception Handling)

num = int(input("Enter a number: "))  # ❌ Crashes if input is non-numeric
print(100 / num)  # ❌ Crashes if input is 0

🔴 Issue: If an error occurs (like division by zero), the program crashes.

Good Code (Using try-except)

try:
    num = int(input("Enter a number: "))
    result = 100 / num
    print(result)
except ValueError:
    print("❌ Please enter a valid number.")
except ZeroDivisionError:
    print("❌ Division by zero is not allowed.")

Why is this better?
Prevents crashes and provides user-friendly error messages.

5️⃣ Using print() for Debugging Instead of logging

Bad Code (Using print() for Debugging)

print("Processing data...")  # ❌ Hard to disable or filter logs

🔴 Issue: print() clutters output and is hard to manage in production.

Good Code (Using logging)

import logging
logging.basicConfig(level=logging.INFO)
logging.info("Processing data...")  # ✅ Easy to control log levels

Why is this better?
✔ Logs can be enabled, disabled, or filtered easily.

6️⃣ Using *args and **kwargs Without Understanding Their Behavior

Bad Code (Using *args Incorrectly)

def my_function(*args):
    print(args[0])  # ❌ IndexError if args is empty

🔴 Issue: Calling my_function() without arguments raises an error.

Good Code (Check Length First)

def my_function(*args):
    if args:
        print(args[0])  # ✅ Works safely

Why is this better?
✔ Prevents IndexError when calling the function with no arguments.

7️⃣ Not Using with Statement for File Handling

Bad Code (Forgetting to Close File)

f = open("file.txt", "r")
content = f.read()
# ❌ Forgot to close file, causing resource leaks

🔴 Issue: Open files waste system resources.

Good Code (Using with Statement)

with open("file.txt", "r") as f:
    content = f.read()  # ✅ File automatically closes

Why is this better?
✔ Ensures file is closed properly.

8️⃣ Misusing List and Dictionary Comprehensions

Bad Code (Inefficient List Comprehension)

even_numbers = []
for i in range(10):
    if i % 2 == 0:
        even_numbers.append(i)  # ❌ Verbose and slow

🔴 Issue: Too many operations, not using Pythonic approach.

Good Code (Using Comprehension)

even_numbers = [i for i in range(10) if i % 2 == 0]  # ✅ More efficient

Why is this better?
Cleaner and faster.

9️⃣ Using == for Floating-Point Comparisons

Bad Code (Floating-Point Comparison Issues)

a = 0.1 + 0.2
print(a == 0.3)  # ❌ False due to floating-point precision

🔴 Issue: Floating-point calculations can be imprecise.

Good Code (Use math.isclose())

import math
a = 0.1 + 0.2
print(math.isclose(a, 0.3, rel_tol=1e-9))  # ✅ True

Why is this better?
Avoids floating-point precision issues.

🔟 Hardcoding Sensitive Information

Bad Code (Exposing API Keys & Passwords)

API_KEY = "my_secret_api_key"  # ❌ Security risk

🔴 Issue: Hardcoded credentials can be leaked.

Good Code (Using Environment Variables)

import os
API_KEY = os.getenv("API_KEY")  # ✅ Secure way to access keys

Why is this better?
Prevents credential exposure.

🎯 Conclusion

By avoiding these 10 common Python mistakes, you can write cleaner, safer, and more efficient code.

Key Takeaways:
Handle errors properly to prevent crashes.
Use Pythonic techniques like list comprehensions.
Avoid security risks by not hardcoding sensitive data.
Leverage built-in Python features for better efficiency.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare