Lists, dicts and comprehensions
Slicing, mutability gotchas, comprehension syntax, and choosing the right collection for the job.
Lists
nums = [3, 1, 2]
nums.append(4) # [3, 1, 2, 4]
nums.extend([5, 6])
nums.insert(0, 0)
last = nums.pop() # removes and returns the last item
nums.sort() # in place; sorted(nums) returns a copy
first, *rest = nums # unpacking| Operation | Cost |
|---|---|
| Index / append / pop from end | O(1) |
| Insert or delete at the front | O(n) β use deque |
x in list | O(n) β use a set for repeated checks |
The aliasing trap
Assignment copies the reference, so two names can point at one list. The classic bug is a default mutable argument, which is evaluated once at definition time and shared by every call.
a = [1, 2]
b = a
b.append(3)
print(a) # [1, 2, 3] - same object
b = a[:] # shallow copy
b = list(a)
# wrong: the default list is shared between calls
def add(item, bucket=[]):
bucket.append(item)
return bucket
# right
def add(item, bucket=None):
bucket = bucket if bucket is not None else []
bucket.append(item)
return bucketβ οΈ
[[0]] * 3 creates three references to the same inner list β changing one changes all. Use a comprehension: [[0] for _ in range(3)].Comprehensions
squares = [n * n for n in range(10)]
evens = [n for n in nums if n % 2 == 0]
# dict comprehension
by_id = {u['id']: u for u in users}
# conditional transformation
labels = ['even' if n % 2 == 0 else 'odd' for n in nums]
# set comprehension - deduplicates
unique_tags = {t.lower() for t in tags}Read them right to left: the expression first, then the loop, then the filter. If a comprehension needs more than one condition or a nested loop, a plain for block is clearer.
Dicts
user = {'id': 1, 'name': 'Ada'}
user.get('email') # None instead of KeyError
user.get('email', 'n/a') # with default
user.setdefault('role', 'guest')
for key, value in user.items():
print(key, value)
merged = {**user, 'role': 'admin'} # Python 3.5+
counts = dict(Counter(words)) # tallying done for youπ‘
Dicts preserve insertion order (guaranteed since 3.7), so you rarely need
OrderedDict anymore. Use collections.defaultdict when building groups.FAQ
tuple or list?
Lists for homogeneous sequences that change size; tuples for fixed-shape records (coordinates, return values). Tuples are also hashable, so they work as dict keys.
Why is my loop skipping items while removing?
Mutating a list while iterating it shifts subsequent indices. Iterate over a copy (
for x in list[:]) or build a new list with a comprehension.Related
Python: getting started Functions and modules
Last refreshed 2026-09-17.