Python Fundamentals
Lists
A list is an ordered, mutable collection that can hold items of any type — even mixed types.
Jr Codex Python Notes
Level: Beginner Prerequisites: Chapter 5 Time to complete: ~25 minutes
Table of Contents
- What is a List?
- Indexing & Slicing
- Lists Are Mutable
- Common List Methods
- Copying Lists — a Common Trap
- Nested Lists
- Sorting
- Summary & Next Steps
1. What is a List?
A list is an ordered, mutable collection that can hold items of any type — even mixed types.
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = ["Alice", 25, True, 3.14]
empty = []
print(len(fruits)) # 32. Indexing & Slicing
Lists use the same indexing/slicing rules as strings (Chapter 4) — no coincidence, both are sequences.
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[0]) # 'apple'
print(fruits[-1]) # 'date'
print(fruits[1:3]) # ['banana', 'cherry']
print(fruits[::-1]) # ['date', 'cherry', 'banana', 'apple'] — reversed3. Lists Are Mutable
Unlike strings, lists can be changed in place — this is the key distinction to internalize.
fruits = ["apple", "banana", "cherry"]
fruits[0] = "avocado" # ✓ allowed — strings would raise TypeError here
print(fruits) # ['avocado', 'banana', 'cherry']
fruits.append("date") # add to the end
fruits.insert(1, "blueberry") # insert at index 1
fruits.remove("banana") # remove by value
popped = fruits.pop() # remove & return last item
del fruits[0] # remove by indexMutability Matters
─────────────────────────────────────────
a = [1, 2, 3]
b = a ← b points to the SAME list object as a
b.append(4)
print(a) ← [1, 2, 3, 4] — a changed too! Same object.
─────────────────────────────────────────
This is the same identity-vs-equality concept from Chapter 3 (is vs ==), now with real consequences.
4. Common List Methods
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.append(10) # add to end → [3,1,4,1,5,9,2,6,10]
nums.extend([7, 8]) # add multiple → [...,10,7,8]
nums.insert(0, 100) # insert at index → [100,3,1,4,...]
nums.remove(1) # remove FIRST '1' → removes one occurrence
nums.pop() # remove & return last item
nums.pop(0) # remove & return item at index 0
nums.count(1) # how many times '1' appears
nums.index(4) # index of first '4'
nums.reverse() # reverse in place
nums.clear() # empty the list| Method | Effect | Returns |
|---|---|---|
.append(x) | Add x to the end | None (modifies in place) |
.extend(iterable) | Add all items from iterable | None |
.insert(i, x) | Insert x at index i | None |
.remove(x) | Remove first occurrence of x | None (raises ValueError if missing) |
.pop(i=-1) | Remove & return item at index i (default: last) | The removed item |
.index(x) | Find index of first x | int (raises ValueError if missing) |
.count(x) | Count occurrences of x | int |
.sort() | Sort in place | None |
.reverse() | Reverse in place | None |
.clear() | Remove all items | None |
+= vs .append() — a Subtle Trap
a = [1, 2, 3]
b = a
b += [4] # in-place extend — modifies the SAME object a points to
print(a) # [1, 2, 3, 4] — a changed!
c = [1, 2, 3]
d = c
d = d + [4] # creates a NEW list — does NOT modify c
print(c) # [1, 2, 3] — unchanged5. Copying Lists — a Common Trap
Because lists are mutable, b = a does not copy — it aliases. To actually copy:
original = [1, 2, 3]
alias = original # ✗ NOT a copy — same object
shallow_copy_1 = original.copy() # ✓ copy
shallow_copy_2 = original[:] # ✓ copy (slicing the whole list)
shallow_copy_3 = list(original) # ✓ copy
shallow_copy_1.append(4)
print(original) # [1, 2, 3] — unaffectedShallow copy caveat: if the list contains nested lists, the inner lists are still shared:
import copy
nested = [[1, 2], [3, 4]]
shallow = nested.copy()
shallow[0].append(99)
print(nested) # [[1, 2, 99], [3, 4]] — inner list changed in BOTH!
deep = copy.deepcopy(nested)
deep[0].append(100)
print(nested) # unaffected — deepcopy copies all nested levels too6. Nested Lists
Lists can contain other lists — commonly used to represent grids, matrices, or rows of data (a preview of what NumPy arrays formalize in Module 6):
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(matrix[1]) # [4, 5, 6] — second row
print(matrix[1][2]) # 6 — row 1, column 2
for row in matrix:
print(row)7. Sorting
nums = [5, 2, 8, 1, 9]
nums.sort() # in place, ascending: [1, 2, 5, 8, 9]
nums.sort(reverse=True) # in place, descending: [9, 8, 5, 2, 1]
original = [5, 2, 8, 1, 9]
new_list = sorted(original) # returns a NEW sorted list, original unchanged
words = ["banana", "kiwi", "apple"]
words.sort(key=len) # sort by a custom key function
print(words) # ['kiwi', 'apple', 'banana'] — shortest to longest.sort() | sorted() | |
|---|---|---|
| Modifies original? | Yes (in place) | No (returns new list) |
| Works on any iterable? | No — list method only | Yes — works on tuples, strings, dicts, etc. |
| Returns | None | New sorted list |
8. Summary & Next Steps
Key Takeaways
- Lists are ordered and mutable — you can change, add, or remove items after creation.
b = aaliases (same object); use.copy(),[:], orlist()for a real (shallow) copy, andcopy.deepcopy()for nested structures..sort()mutates in place;sorted()returns a new list — pick based on whether you need the original preserved.- Nested lists (lists of lists) are the basis for grid/matrix-style data, revisited with NumPy in Module 6.
Concept Check
- Why does
b = a; b.append(4)also changea? - What's the difference between
.remove(x)anddel my_list[i]? - When would you use
copy.deepcopy()instead of.copy()?
Next Chapter
→ Chapter 7: Tuples & Sequence Unpacking
Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index