Lists are mutable; tuples are immutable ordered sequences. Immutability guarantees data cannot change accidentally—critical for hashable records used as dictionary keys, fixed dataset schemas, and coordinates returned from functions.
In AI pipelines, tuples represent things that must not drift: a (height, width) image shape, a (mean, std) normalization pair, or a labeled sample (features_tuple, label) stored in a set for deduplication.
Learning Objectives
By the end of this lesson, students should be able to:
- Create tuples with parentheses or trailing commas.
- Explain immutability and its implications for hashing and safety.
- Access tuple elements by index and slice like lists.
- Unpack tuples into multiple variables.
- Use tuples as dictionary keys and function return bundles.
- Choose tuple vs list for fixed-schema AI records.
Creating Tuples
A tuple is an ordered, immutable sequence of objects, written with parentheses (or commas alone). Once created, elements cannot be added, removed, or reassigned. Immutability makes tuples hashable when all elements are hashable.
Immutability in Practice
List (mutable)
losses.append(0.3)OK- Cannot use as dict key
- Grows during training logs
- Flexible, in-place updates
Tuple (immutable)
shape[0] = 256raises TypeError- Hashable if elements are hashable
- Fixed records and coordinates
- Signals “do not modify”
Unpacking and Returning Tuples
Functions often return multiple values as a tuple, unpacked at the call site. This pattern is ubiquitous in train/validation splits and min-max computations.
| Pattern | Example | AI Use |
|---|---|---|
| Return bundle | return train, val |
Dataset split |
| Unpack | mean, std = compute_stats(x) |
Normalization parameters |
| Star unpack | first, *rest = epochs |
Separate warmup epoch |
| Swap | a, b = b, a |
Reorder without temp variable |
When to Choose Tuple vs List
| Scenario | Prefer | Reason |
|---|---|---|
| Growing loss history | List | Needs append |
| Fixed image shape | Tuple | Immutable contract |
| Dict key for cache | Tuple | Hashable |
| Batch of samples | List | Mutable, variable length |
Common Misconceptions
Why people believe it: Similar indexing and slicing syntax.
Reality: Immutability is semantic, not just operational. Tuples signal fixed structure; they are hashable when elements are hashable—lists are not.
Why people believe it: The tuple object itself cannot be reassigned.
Reality: A tuple of lists is hashable only if all elements are hashable—lists inside tuples can still be mutated. For true immutability, use nested tuples or frozen data structures.
Why people believe it: Textbooks show (1, 2, 3).
Reality: Commas create tuples: a = 1, 2, 3. Parentheses disambiguate in expressions like (x + y,).
Quick Knowledge Check
- Short Answer: Main difference between list and tuple? Answer: Tuples are immutable; lists are mutable.
- True/False: Tuples can be dictionary keys if hashable. Answer: True.
- Multiple Choice:
(42)type is: (a) tuple, (b) int, (c) list, (d) set. Answer: (b) — need (42,) for tuple. - Short Answer: Write a tuple for RGB color (255, 128, 0). Answer: (255, 128, 0).
- True/False:
shape[0] = 256works on a tuple. Answer: False. - Short Answer: What does
a, b = fn()assumefnreturns? Answer: An iterable of two values (often a tuple). - Multiple Choice: Best type for fixed (height, width): (a) list, (b) tuple, (c) dict, (d) set. Answer: (b).
- True/False: Tuple slicing returns a new tuple. Answer: True.
- Short Answer: Why return normalization stats as a tuple? Answer: Immutable fixed pair for reuse at inference.
- Multiple Choice: Tuple with a list inside is hashable? Answer: No — list is unhashable.
Key Takeaways
- Tuples are ordered, immutable sequences created with commas/parentheses.
- Immutability enables hashable records usable as dictionary keys and cache indices.
- Unpacking tuples cleanly binds multiple return values:
scaled, stats = fn(). - Use tuples for fixed schemas (shapes, stats pairs); lists for growing collections.
- Tuples inside tuples are safer keys than tuples containing mutable lists.
- Next: Set for unique-element collections.
Hands-on idea: Implement a shape-keyed cache dict using (batch, seq_len, dim) tuples as keys.
Debugging exercise: Show (42) vs (42,) with type().
Discussion prompt: Should train/val split indices be stored as lists or tuples?