Lists + Tuples
Ordered collections and essential methods
Why it matters
Lists are the default container for most problems. Tuples lock data safely.
The idea
Lists are flexible shelves; tuples are sealed boxes. Tuples are hashable (can be dict keys, set members), lists are not.
Try it
List basics — append, extend, slice, comprehension:
xs = [1, 2, 3]
xs.append(4) # in place
xs.extend([5, 6]) # in place
xs += [7] # in place too
print(xs)
# Comprehension — the Pythonic loop
squares = [x*x for x in xs if x % 2 == 0]
print(squares)
Tuples are immutable, support unpacking, and can be dict keys:
origin = (0, 0)
def move(point, dx, dy):
x, y = point # unpacking
return (x + dx, y + dy)
print(move(origin, 3, 4))
routes = { (0, 0): "home", (3, 4): "park" }
print(routes[(3, 4)])
Sorting — in place vs return new:
words = ["apple", "Banana", "cherry"]
print(sorted(words)) # case-sensitive
print(sorted(words, key=str.lower)) # case-insensitive
print(sorted(words, key=len, reverse=True))
# In place — returns None! (common bug)
words.sort()
print(words)
List methods (complete essentials)
| Method | What it does | Example |
| --- | --- | --- |
| append(x) | add one item | nums.append(5) |
| extend(iter) | add many | nums.extend([6,7]) |
| insert(i,x) | add at index | nums.insert(1, 42) |
| remove(x) | remove first match | nums.remove(2) |
| pop(i) | remove by index | nums.pop() |
| clear() | remove all | nums.clear() |
| index(x) | find position | nums.index(3) |
| count(x) | count value | nums.count(3) |
| sort() | sort in place | nums.sort() |
| reverse() | reverse in place | nums.reverse() |
| copy() | shallow copy | nums.copy() |
List as stack / queue
A list makes a fine stack (append / pop off the end). For a fast queue, reach for collections.deque — popping from the front of a list is O(n):
from collections import deque
q = deque([1, 2, 3])
q.append(4) # enqueue
q.popleft() # dequeue — O(1)
Copy vs alias (important)
a = [1, 2, 3]
b = a # alias — same list, mutations are shared
c = a.copy() # new list — independent
Nested list trap
[[0] * 3] * 3 repeats the same inner row three times — mutating one mutates all:
grid = [[0] * 3] * 3 # WRONG: shared rows
grid = [[0] * 3 for _ in range(3)] # correct: independent rows
Quick check
- Q: What does
b = acreate? A: An alias (same list).
Mini drills
- Sum a list without
sum(). - Remove duplicates from a sorted list (concept).
- Insert a value at index 2.
Do's and don'ts
- Do use
appendfor single items andextendfor many. - Don't assume
sort()returns a new list. - Don't build nested lists with
[[x]*n]*m.
Going deeper — complexity snapshot
- Index access: O(1)
- Append: O(1) amortized
- Insert/remove at front: O(n)
- Membership (
x in lst): O(n)
Common mistakes
- Mistake: Modifying a list while iterating. Fix: Iterate over a copy or use indices.
- Mistake: Confusing alias with copy. Fix: Use
list(a)ora.copy(). - Mistake:
new = nums.sort()givesNone. Fix: Usesorted(nums).
Key takeaways
listis mutable;tupleis immutable + hashable.- Comprehensions are faster + clearer than
for+append. sorted(x)returns a new list;x.sort()mutates and returnsNone.key=accepts a function:key=str.lower,key=len,key=lambda t: t[1].b = ashares the same list; usea.copy()for an independent one.