Skip to main content

Common Python Mistakes - Avoid These Errors šŸ›

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​

TipHow to Do It
Print debuggingAdd print() statements at key points to check variable values
Use repr()print(repr(obj)) shows exact string representation including special chars
Python's -i flagpython -i script.py drops into interactive shell after execution
Use pdbInsert import pdb; pdb.set_trace() for an interactive debugger
Check typesUse type() and isinstance() to verify data types
Read tracebacksStart from the bottom-most error and work upward
Simplify the problemCreate a minimal script that reproduces the bug
Rubber duck debuggingExplain your code line by line to a rubber duck (or colleague)

šŸ“Š Mistake Categories​

CategoryMistakesDescription
Syntax Errors#3, #7, #11Code violates Python grammar rules; interpreter cannot parse
Logic Errors#1, #2, #4, #5, #9, #10, #11, #13Code runs without crashing but produces wrong results
Performance Issues#14Code works but is unnecessarily slow
Style / Maintainability#8, #12, #15Code works but is hard to read, debug, or maintain


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.