← Back to Python Course | Chapter 14: Advanced Python & Tools | Lesson 4 of 15

Python Common Mistakes

Mutable Default Arguments Trap

Using a mutable object like a list or dict as a function's default parameter value is a classic Python trap: default values are evaluated only once, at function-definition time, so every call that doesn't pass its own argument ends up sharing and mutating that exact same object.

Example: Mutable Default Arguments Trap

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

print(add_item("apple"))
print(add_item("banana"))  # unexpectedly shares the same list

Modifying Lists During Iteration

Removing or inserting items from a list while iterating over it directly shifts the underlying indices mid-loop, causing Python to silently skip elements or raise an unexpected IndexError. The safe fix is to iterate over a copy of the list (for x in list[:]) or build a new filtered list instead of mutating the original in place.

Example: Modifying Lists During Iteration

python
numbers = [1, 2, 3, 4]
for n in numbers[:]:  # iterate over a copy
    if n % 2 == 0:
        numbers.remove(n)
print(numbers)

Shadowing Built-in Functions

Naming a variable list, dict, str, or another built-in overwrites that name within the current scope, so any later code in that scope that tries to use the real built-in (like calling list() to make a new list) breaks with a confusing TypeError instead of a clear naming-conflict warning.

Example: Shadowing Built-in Functions

python
list = [1, 2, 3]  # shadows the built-in list()
print(list)
del list  # restore the built-in
print(list([4, 5]))

Checking with is vs ==

== compares whether two objects have equal *values*, while is compares whether two names refer to the exact same object in memory. Two separately-created lists with identical contents are equal (== is True) but are not the same object (is is False) -- conflating the two leads to subtle bugs, especially with None checks, which should always use is None.

Example: Checking with is vs ==

python
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)
print(a is b)

Referencing Before Assignment

Reading a local variable before any value has been assigned to it inside the same function raises UnboundLocalError, even if a variable with the same name exists at module scope -- because assigning anywhere inside a function makes Python treat that name as local for the *entire* function body, not just from the assignment line onward.

Example: Referencing Before Assignment

python
def show():
    try:
        print(count)
        count = 1
    except UnboundLocalError as e:
        print("Error:", e)

count = 10
show()

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.