Skip to main content
Common mistakes2026-05-14 · 7 min read

5 Python mistakes every beginner makes (and how to fix them in 2026)

Most Python beginners hit the same five walls. Once you know they're coming, you avoid them entirely. Here they are, with the fix for each.

Mistake 1: Mutable default arguments

The trap:

\\\`python

def add_item(item, items=[]):

items.append(item)

return items

print(add_item("a")) # ["a"]

print(add_item("b")) # ["a", "b"] ← surprise!

\\\`

The list default is created once at function definition time, not each call. Every call mutates the same list.

The fix:

\\\`python

def add_item(item, items=None):

if items is None:

items = []

items.append(item)

return items

\\\`

Rule: never use mutable objects (\[]\, \{}\, \set()\) as default arguments. Use \None\ and create them inside the function.

Mistake 2: Confusing copy and reference

The trap:

\\\`python

a = [1, 2, 3]

b = a # b is the SAME list, not a copy

b.append(4)

print(a) # [1, 2, 3, 4] ← oops

\\\`

The fix:

\\\`python

b = a.copy() # shallow copy

OR

b = list(a) # also shallow copy

OR

import copy

b = copy.deepcopy(a) # full deep copy (for nested structures)

\\\`

For nested structures (lists of lists, dicts of lists), \.copy()\ is not enough. You need \copy.deepcopy()\.

Mistake 3: Using \==\ instead of \is\ (or vice versa)

The trap:

\\\`python

x = None

if x == None: # works but un-Pythonic

...

if a == b: # value equality

...

if a is b: # identity (same object in memory)

...

\\\`

The fix: use \is\ for None, True, False. Use \==\ for everything else.

\\\`python

if x is None: # correct

if value == 42: # correct

if name == "Ada": # correct

\\\`

\is\ checks memory identity. \==\ checks logical equality. \x is 0\ happens to work in current CPython for small ints (interned), but you're relying on an implementation detail. Don't.

Mistake 4: Mixing \for i in range(len(items))\ with iteration

The trap (un-Pythonic):

\\\`python

for i in range(len(items)):

print(items[i])

\\\`

The fix (Pythonic):

\\\`python

for item in items:

print(item)

If you need the index too:

for i, item in enumerate(items):

print(i, item)

\\\`

\enumerate\ exists exactly so you don't need \range(len(...))\. The Pythonic version is also faster and clearer.

Mistake 5: Catching all exceptions silently

The trap:

\\\`python

try:

do_something()

except:

pass # ← swallows EVERY error, including KeyboardInterrupt and bugs

\\\`

The fix:

\\\`python

try:

do_something()

except ValueError as e:

log.warning("bad input: %s", e)

\\\`

Rule: catch the specific exception you expect. If you must catch everything, at least log it. Bare \except: pass\ is the #1 reason beginner code has invisible bugs that show up six months later in production.

Bonus: forgetting that strings are immutable

\\\`python

s = "hello"

s[0] = "H" # TypeError — strings can't be modified in place

\\\`

The fix:

\\\`python

s = "H" + s[1:] # or

s = s.replace("h", "H", 1)

\\\`

This catches almost every beginner the first time they try to modify a string. Strings are immutable. You create a new one.

How to internalize these

Reading is not enough. Open a Python REPL (or our interactive lessons) and reproduce each trap. Run the broken code, see the bug, write the fix, run it again. That muscle memory is what makes you actually avoid these in your own code.

Our Common Mistakes track covers all five of these plus 15 more in interactive, runnable form — with an AI tutor that explains why each one breaks.

cta_title

cta_body

cta_button

Get one Python lesson + one career idea every Friday

No spam, no "buy our course now". Three bullets, every Friday. Unsubscribe with one click.