Python Fundamentals Review
The 20% of Python you use 95% of the time
The data-science-relevant slice of Python: dynamic typing, built-in types, operators, truthiness and the iteration protocol — enough to read and write pandas and numpy idiomatically.
What you will learn
- Distinguish immutable vs mutable types
- Use truthiness and operator quirks without surprises
- Understand the iteration/for-loop protocol
What is this?
Data science leans on a narrow slice of Python: numbers, strings, booleans; the container types (list, dict, set, tuple); dynamic typing; and iteration. Getting the core semantics — what's mutable, what's `True`, what `.copy()` actually copies — prevents the silent bugs that plague notebooks.
Why do you need it?
- pandas and numpy are Python objects; Python semantics leak through (e.g., in-place mutation surprises).
- Half of all 'wait, why did my column change?' mysteries are aliasing/mutation bugs.
- List/dict comprehension fluency is the day-to-day speed diff between engineers.
- Truthiness rules are why `if df['col']:` breaks mysteriously.
Mental model
A toolbox where a few tools do 90% of the work
Python builtins for data science
list, dict, set, tuple, range, zip, enumerate, sorted, len, sum — every notebook is built from these plus the scientific libraries.
How it works
- Everything is an object with a type; `type(x)` and `isinstance(x, bool)` reveal it.
- Immutable (int, float, str, tuple, frozenset) vs mutable (list, set, dict): mutation changes identity in place.
- Assignment copies references, not data: `b = a` aliases; `b = a.copy()` duplicates.
- Truthiness: 0, 0.0, '', [], {}, None are falsy; everything else truthy.
- `for x in seq` calls `iter(seq)` then `next` repeatedly — the protocol pandas and numpy build on.
Python object basics.
Examples
Aliasing vs copying traps
a = [1, 2, 3]b = a # alias — same objectc = a.copy() # new objectb.append(4)print(a) # [1, 2, 3, 4] → b mutated aprint(c) # [1, 2, 3] → copy safe`b = a` created a reference, so mutating b changed a. In pandas-land this is why you sometimes mutate frames unexpectedly — always confirm whether an API operates in place or returns a copy.
In production
- A notebook bug where a shared list was appended to by a loop 'corrupted' all lookups — an aliasing issue.
- A data pipeline uses tuple keys for immutability in a dict of aggregates.
- Deep vs shallow copies of nested lists cause silent edits when preprocessing data.
Best practices
- Prefer tuples for fixed records and dicts for lookup tables.
- Use .copy() explicitly whenever you plan to mutate a passed-in container.
- Test truthiness-of-empty containers instead of `is not None`.
Common mistakes
- Using a mutable default argument (`def f(x=[])`) — the default is shared across calls.
- Mutating a list while iterating over it.
- `if list:` checks non-empty — mixing that with `if x is not None` semantics.
Debugging tips
- id(x) reveals aliasing: same id = same object.
- For 'phantom mutation', check where a reference to the object escaped.
- Test with `==` for values and `is` for singletons (None).
Interview checkpoint
Quick quiz
Which of these is IMMUTABLE in Python?
`b = a.copy()` and `b = a` are equivalent.