5 Common Python Mistakes and How to Fix Them
Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Configure your editor/IDE to translate tabs to spaces to prevent indentation errors that appear correct visually.
Briefing
Python’s most common “mystery errors” often come down to a handful of avoidable habits: inconsistent indentation, naming conflicts, mutable defaults, iterator exhaustion, and wildcard imports. Fixing these issues early prevents time-wasting debugging—especially when code looks correct at a glance but fails at runtime.
The first pitfall is mixing tabs and spaces, which triggers indentation errors like “IndentationError: unindent does not match any outer indentation level.” The transcript shows how a program can appear aligned in a text editor while Python still treats the indentation levels as mismatched. The practical fix is to use an editor or IDE setting that automatically translates tabs to spaces (the example uses Sublime Text’s “translate tabs to spaces” setting). For extra safety, a linter such as pylint can catch problems that are easy to miss visually.
Next comes a naming conflict that breaks imports in a way that can be confusing: creating a local module with the same name as a standard-library module. The example creates a file named math.py (and then uses “from math import radians” and “sine”), but Python prioritizes the local module over the standard library. The result is an import error (“cannot import name radians for math”). Renaming the local file (e.g., to project_PI) restores the intended import from the real standard-library math module. The same issue can happen with third-party packages like Flask or Django if a local file or package shadows those names.
A related mistake involves variable shadowing. If a variable is named the same as an imported function—such as assigning radians = radians(90 degrees)—the function reference gets overwritten by a float value. Later, calling radians(45 degrees) fails with “float object is not callable.” The fix is simple: avoid reusing imported function names for variables (use a different variable name like rads or rad_90).
Mutable default arguments are another classic trap. Default parameter values are evaluated once when the function is defined, not each time it’s called. The transcript demonstrates a function add_employee(employee, employee_list=[]) where repeated calls without passing employee_list keep appending to the same list instance. The remedy is to use employee_list=None and create a new list inside the function when the argument is None. The same principle applies to other defaults like date/time.now: if it’s set as a default value, it won’t update across calls.
Iterator exhaustion explains a common Python 2 vs Python 3 surprise. In Python 3, zip returns an iterator rather than a fully materialized list. Converting that iterator to a list consumes it; attempting to iterate over it again yields no results. The fix is to convert zip to a list once and then iterate over that list, or otherwise avoid reusing an exhausted iterator.
Finally, wildcard imports (from module import *) make code harder to debug and can silently overwrite names. The transcript shows how importing * from multiple modules can cause one function (like escape) to replace another, leading to confusing behavior. The recommended approach is explicit imports—either import the module and use module.function, or import specific names directly—so it’s always clear where each symbol comes from.
Cornell Notes
The transcript identifies five recurring Python mistakes that lead to confusing runtime errors: mixed tabs/spaces, import shadowing, variable shadowing, mutable default arguments, and iterator exhaustion—plus a related bad practice with wildcard imports. Indentation errors happen when editors insert different whitespace types; fix it by configuring the editor to translate tabs to spaces and using tools like pylint. Import and variable shadowing occur when local files or variables reuse names from standard-library or imported functions, breaking expected references. Mutable defaults (like []) are evaluated once, so repeated calls reuse the same object; use None and create a new list inside the function. In Python 3, zip is an iterator that gets exhausted when consumed, so materialize it once if it must be reused.
Why does mixing tabs and spaces cause errors even when code “looks” aligned?
How can naming a local file break standard-library imports?
What does variable shadowing do to imported functions?
Why do mutable default arguments behave unexpectedly across function calls?
What does “iterator exhaustion” mean for zip in Python 3?
Why are wildcard imports (from X import *) risky?
Review Questions
- What specific mechanism causes mutable default arguments like [] to persist across calls, and how does using None change the behavior?
- In Python 3, what happens when you convert a zip iterator to a list and then try to iterate over the original zip object again?
- How do import shadowing and variable shadowing differ, and what symptoms would each produce at runtime?
Key Points
- 1
Configure your editor/IDE to translate tabs to spaces to prevent indentation errors that appear correct visually.
- 2
Avoid naming local modules or packages the same as standard-library modules or third-party packages you intend to import.
- 3
Do not reuse imported function names for variables; shadowing can turn callables into non-callable values and trigger runtime errors.
- 4
Replace mutable default arguments (like []) with None and create new objects inside the function.
- 5
Compute time-dependent defaults (like date/time.now) inside the function rather than as default parameter values.
- 6
Treat Python 3 zip as an iterator: materialize it once (e.g., list(zip(...))) if you need to iterate multiple times.
- 7
Use explicit imports instead of wildcard imports to prevent hidden name origins and accidental overwrites.