Common Python Mistakes - Avoid These Errors š
Common Python Mistakes - Avoid These Errors is a core Python concept covering 15+ common Python mistakes explained with wrong and correct code examples. Covers syntax errors, logic bugs, performance pitfalls, and style issues. This topic is essential for academic learning, board exam preparation, and developing optimized real-world code.
Every Python developer makes mistakes. This guide covers the most common ones, explains why they happen, and shows the correct approach. Learn from others' errors and write better code.
Reference: For a deeper standalone reference with production-grade examples, see the Python Common Mistakes reference.
1. Mutable Default Argumentsā
Using a mutable object (list, dict, set) as a default argument. The default is created once at function definition, not each call.
Wrong:
def add_item(item, items=[]):
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] -- unexpected!
Correct:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [2]
2. Modifying a List While Iteratingā
Adding or removing elements from a list while looping over it causes skipped elements or index errors.
Wrong:
numbers = [1, 2, 3, 4, 5]
for n in numbers:
if n % 2 == 0:
numbers.remove(n)
print(numbers) # [1, 3, 5] -- 4 was skipped!
Correct:
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]
print(numbers) # [1, 3, 5]
3. Using = Instead of ==ā
Assignment (=) instead of comparison (==) in conditions.
Wrong:
if x = 5: # SyntaxError or unexpected assignment
print("x is 5")
Correct:
if x == 5:
print("x is 5")
4. Forgetting to Return from a Functionā
A function without an explicit return statement returns None.
Wrong:
def add(a, b):
result = a + b
# no return statement
print(add(3, 4)) # None
Correct:
def add(a, b):
return a + b
print(add(3, 4)) # 7
5. Using is for Value Comparisonā
is checks identity (same object), not equality (same value).
Wrong:
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # False -- different objects
Correct:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True -- same values
Use is None, is True, is False only for singletons.
6. Not Handling Exceptionsā
Letting your program crash when errors are predictable.
Wrong:
x = int(input("Enter a number: "))
result = 10 / x # Crashes if x is 0 or input is not a number
Correct:
try:
x = int(input("Enter a number: "))
result = 10 / x
print(f"Result: {result}")
except ValueError:
print("Please enter a valid number.")
except ZeroDivisionError:
print("Cannot divide by zero.")
See Exception Handling.
7. Indentation Errorsā
Inconsistent use of spaces and tabs, or incorrect indentation levels.
Wrong:
def hello():
print("Hello") # IndentationError
print("World") # Wrong level
Correct:
def hello():
print("Hello")
print("World")
Use 4 spaces per level consistently. Configure your editor to convert tabs to spaces.
8. Variable Shadowingā
Using the same name for a local variable as a built-in function or outer variable.
Wrong:
list = [1, 2, 3] # Shadows built-in list()
print(list(range(5))) # TypeError: 'list' object is not callable
Correct:
my_list = [1, 2, 3]
print(list(range(5))) # [0, 1, 2, 3, 4]
Avoid shadowing: str, int, input, max, min, sum, type, file, id.
9. Misunderstanding Scope (LEGB Rule)ā
Python resolves names in order: Local ā Enclosing ā Global ā Built-in.
Wrong:
x = 10
def change_x():
x = 5 # Creates a new local x, does not modify global
change_x()
print(x) # 10 -- unchanged!
Correct:
x = 10
def change_x():
global x
x = 5
change_x()
print(x) # 5
10. Using Mutable Objects as Dictionary Keysā
Dictionary keys must be hashable. Mutable types like lists and dicts are not hashable.
Wrong:
data = {[1, 2]: "value"} # TypeError: unhashable type: 'list'
Correct:
data = {(1, 2): "value"} # Tuple is immutable and hashable
11. Confusing == and inā
Using == when you mean in (membership), or vice versa.
Wrong:
if color == "red" or "blue": # Always True! "blue" is truthy
print("Valid color")
Correct:
if color == "red" or color == "blue":
print("Valid color")
# Or better:
if color in ("red", "blue"):
print("Valid color")
12. Not Using with for File I/Oā
Opening files without with leaves them open, risking resource leaks.
Wrong:
f = open("file.txt", "r")
content = f.read()
# If an exception occurs here, f is never closed
f.close()
Correct:
with open("file.txt", "r") as f:
content = f.read()
# File is automatically closed, even on exceptions
See File Handling.
13. Off-by-One Errors in range()ā
Forgetting that range() excludes the stop value.
Wrong:
for i in range(5):
print(i) # Prints 0 to 4, not 1 to 5
# Printing 1 to 5:
for i in range(5):
print(i + 1) # Off-by-one logic
Correct:
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
14. Inefficient String Concatenation in Loopsā
Using += on strings in loops creates a new string each iteration (O(n²)).
Wrong:
result = ""
for word in words:
result += word + " " # Inefficient for large lists
Correct:
result = " ".join(words) # O(n) - creates one string
15. Misusing Global Variablesā
Relying heavily on global variables makes code hard to debug, test, and reuse.
Wrong:
total = 0
def add_to_total(x):
global total
total += x
Correct:
def add_to_total(total, x):
return total + x
Pass data through parameters and return values instead.
š Debugging Tipsā
| Tip | How to Do It |
|---|---|
| Print debugging | Add print() statements at key points to check variable values |
Use repr() | print(repr(obj)) shows exact string representation including special chars |
Python's -i flag | python -i script.py drops into interactive shell after execution |
Use pdb | Insert import pdb; pdb.set_trace() for an interactive debugger |
| Check types | Use type() and isinstance() to verify data types |
| Read tracebacks | Start from the bottom-most error and work upward |
| Simplify the problem | Create a minimal script that reproduces the bug |
| Rubber duck debugging | Explain your code line by line to a rubber duck (or colleague) |
š Mistake Categoriesā
| Category | Mistakes | Description |
|---|---|---|
| Syntax Errors | #3, #7, #11 | Code violates Python grammar rules; interpreter cannot parse |
| Logic Errors | #1, #2, #4, #5, #9, #10, #11, #13 | Code runs without crashing but produces wrong results |
| Performance Issues | #14 | Code works but is unnecessarily slow |
| Style / Maintainability | #8, #12, #15 | Code works but is hard to read, debug, or maintain |
š Related Resourcesā
- Exception Handling ā Proper error handling
- Variables & Data Types ā Scope and mutability
- Functions ā Proper function design
- File Handling ā File I/O best practices
- PEP 8 ā Style guide
- Debugging (pdb) ā Debugging techniques
Mistakes are part of learning. The best developers are not the ones who never make mistakes ā they are the ones who know how to find and fix them quickly.