root@vm-learning
~
$
open
ch-2-12
UNIT 2 ▪ CHAPTER 12
18
Tuples
Creation · Indexing · Unpacking · Built-ins · Nested Tuples
A tuple is an ordered, immutable sequence of values — essentially a read-only list. Tuples are written inside round brackets
( ), with items separated by commas. Because they cannot be modified after creation, tuples are perfect for fixed records: a date (2026, 4, 21), a GPS coordinate (12.97, 77.59), an RGB colour (255, 128, 0), a row returned by a database query. Python itself uses tuples whenever it needs to return several values at once.
Why do we need tuples if we already have lists?
- Immutability is a safety feature — a tuple cannot accidentally be changed by code that receives it.
- Faster & lighter — tuples use a bit less memory and are a little faster to iterate than lists.
- Only immutable objects can be dictionary keys or set elements — lists cannot, tuples can.
- Many Python constructs (multiple return, multiple assignment) use tuples under the hood.
Learning Outcome 1: Create tuples in all their valid forms and apply basic sequence operations.
18.1 Creating a Tuple
| Form | Example | Result |
|---|---|---|
| With parentheses | t = (1, 2, 3) | 3-tuple (1, 2, 3) |
| Without parentheses (comma is what matters) | t = 1, 2, 3 | same (1, 2, 3) |
| Empty tuple | t = () or tuple() | () |
| One-element tuple — needs a trailing comma! | t = (7,) | (7,) |
Not a tuple — (7) is just the integer 7 in parentheses | x = (7) | 7 (int) |
| From any iterable | tuple("ABC") | ('A','B','C') |
| Mixed types allowed | t = (1, "two", 3.0, True) | 4-tuple of mixed types |
The trailing-comma trap for 1-tuples catches every beginner:
print(type((7))) # <class 'int'> — just a number in parens print(type((7,))) # <class 'tuple'> — the comma makes it a tuple print(type(7,)) # <class 'tuple'> — parens optionalWithout the comma, Python treats the parentheses as grouping an expression.
18.2 Indexing
Indexing works exactly as on strings and lists — positive indices from the left start at 0; negative indices from the right start at −1.
Tuple indexing:
days = ("Mon", "Tue", "Wed", "Thu", "Fri") print(days[0]) # 'Mon' print(days[-1]) # 'Fri' print(days[2]) # 'Wed' # print(days[10]) ❌ IndexError: tuple index out of range
18.3 Tuple Operations
18.3.1 Concatenation +
a = (1, 2, 3) b = (4, 5) print(a + b) # (1, 2, 3, 4, 5) — NEW tuple
18.3.2 Repetition *
print((0,) * 4) # (0, 0, 0, 0) — note the trailing comma in the 1-tuple print(("ab", "cd") * 2) # ('ab','cd','ab','cd')
18.3.3 Membership in / not in
days = ("Mon", "Tue", "Wed", "Thu", "Fri") print("Wed" in days) # True print("Sun" not in days) # True
18.3.4 Slicing [start:stop:step]
Slicing returns a new tuple — same rules as strings and lists.
nums = (10, 20, 30, 40, 50, 60) print(nums[1:4]) # (20, 30, 40) print(nums[:3]) # (10, 20, 30) print(nums[::2]) # (10, 30, 50) print(nums[::-1]) # (60, 50, 40, 30, 20, 10) — reverse print(nums[-2:]) # (50, 60)
18.3.5 Length — len()
print(len((1, 2, 3))) # 3 print(len(())) # 0 print(len((7,))) # 1
18.4 Tuples Are Immutable
You can read a tuple's items, but you cannot change, add, or delete any. Python raises TypeError on attempt.
t = (1, 2, 3) # t[0] = 99 ❌ TypeError: 'tuple' object does not support item assignment # t.append(4) ❌ AttributeError — no append method # del t[0] ❌ TypeError # The only way to "change" a tuple is to build a new one: t = (99,) + t[1:] # (99, 2, 3)
If a tuple contains a mutable object (like a list), the list itself can still be mutated — only the tuple's own slot cannot be reassigned:
t = ([1, 2], [3, 4]) t[0].append(99) # ✓ modifying the INNER list is allowed print(t) # ([1, 2, 99], [3, 4])
Learning Outcome 2: Use tuple unpacking (tuple assignment) and nested tuples.
18.5 Tuple Assignment (Unpacking)
Tuple unpacking — also called multiple assignment — lets you split a tuple's items into separate variables in a single line. The number of names on the left must match the number of items on the right.
point = (12.97, 77.59) lat, lon = point # lat = 12.97, lon = 77.59 # Works in many situations — RHS can be any iterable a, b, c = (1, 2, 3) x, y = 10, 20 # no parens needed # Classic 1-line swap (you saw it in Chapter 10): x, y = y, x
Functions that "return multiple values" are actually returning a tuple:
def min_max(nums): return min(nums), max(nums) # returns a 2-tuple lo, hi = min_max([85, 72, 91]) # unpacked on the way in print(lo, hi) # 72 91
18.6 Nested Tuples
A tuple can contain any type — including other tuples. Two indices in a row reach a nested element.
students = (
("Aarav", 85, 72, 91),
("Kavya", 90, 88, 94),
("Ishan", 68, 75, 80)
)
print(students[0]) # ('Aarav', 85, 72, 91)
print(students[1][0]) # 'Kavya' — row 1, column 0
print(students[2][3]) # 80 — row 2, column 3
# Loop over the rows, unpack on the way in:
for name, m1, m2, m3 in students:
print(name, "→", m1 + m2 + m3)
Learning Outcome 3: Apply the built-in functions and methods of a tuple.
18.7 Built-in Functions and Methods
18.7.1 Built-in FUNCTIONS (called as fn(t))
| Function | Effect | Example (t = (3, 1, 4, 1, 5)) |
|---|---|---|
len(t) | Number of items | 5 |
tuple(iter) | Build a tuple from any iterable | tuple("ABC") → ('A','B','C') |
min(t) | Smallest item | 1 |
max(t) | Largest item | 5 |
sum(t) | Sum of numeric items | 14 |
sorted(t) | Return a sorted list (NOT a tuple) — original unchanged | [1, 1, 3, 4, 5] |
reversed(t) | Iterator over items in reverse | tuple(reversed(t)) → (5,1,4,1,3) |
Since
sorted() always returns a list, wrap it in tuple() if you want a tuple back:
print(tuple(sorted(t))) # (1, 1, 3, 4, 5)
18.7.2 Tuple METHODS — only two!
Because tuples cannot be modified, they have no append, pop, sort, etc. The only two methods are read-only queries.
| Method | Returns | Example (t = (3, 1, 4, 1, 5)) |
|---|---|---|
t.count(x) | How many times x appears | t.count(1) → 2; t.count(9) → 0 |
t.index(x) | Index of the first occurrence. Raises ValueError if not found. | t.index(4) → 2 |
Learning Outcome 4: Write the CBSE suggested programs — max/min/mean, linear search, frequency of elements.
18.8 Worked Programs
18.8.1 Maximum, Minimum, Mean of a tuple
nums = (23, 45, 11, 78, 56, 34) # Using built-ins — shortest version print("Max =", max(nums)) print("Min =", min(nums)) print("Mean =", sum(nums) / len(nums)) # Without built-ins — the logic CBSE wants you to show largest = nums[0] smallest = nums[0] total = 0 for x in nums: if x > largest: largest = x if x < smallest: smallest = x total += x print(largest, smallest, total / len(nums))Output:
Max = 78 Min = 11 Mean = 41.166666666666664
18.8.2 Linear search on a tuple
nums = (23, 45, 11, 78, 56, 34) target = int(input("Search for: ")) for i in range(len(nums)): if nums[i] == target: print(target, "found at index", i) break else: # for-else — runs only when no break fired print(target, "is not in the tuple")Sample runs:
Search for: 78 → 78 found at index 3 Search for: 99 → 99 is not in the tuple
Since tuples have a built-in
index() method, you can use it too — but note that it raises ValueError when the target is absent:
if target in nums: print("Found at", nums.index(target)) else: print("Not found")
18.8.3 Frequency of each element
Using
count() with set to find uniques:
nums = (1, 2, 3, 2, 1, 3, 1, 4) for x in set(nums): # set removes duplicates print(x, "→", nums.count(x))Output:
1 → 3 2 → 2 3 → 2 4 → 1
18.9 List vs Tuple — Side-by-Side
| Property | List | Tuple |
|---|---|---|
| Brackets | [ ] | ( ) or none |
| Mutable? | Yes | No |
| Number of methods | ~11 (append, pop, sort, …) | only 2 — count & index |
| Memory / speed | larger; a bit slower | smaller; a bit faster |
| Typical use | a collection that may change | a fixed record, return-multiple-values |
| Can be a dict key / set element? | No — mutable | Yes |
| Conversion | list(iterable) | tuple(iterable) |
| Literal syntax quirks | [] is empty, [x] is 1-element | () empty, (x,) 1-element |
Side-by-side visual comparison:
📌 Quick Revision — Chapter 18 at a Glance
- Tuple = ordered, immutable sequence. Written inside
( )— the commas are what actually make it a tuple. - Creation:
(1,2,3)·1,2,3· empty()· one-element(7,)— trailing comma mandatory! ·tuple("ABC"). - Indexing / slicing: identical to strings and lists.
t[0]first,t[-1]last,t[::-1]reverse. - Operations:
+concat ·*repeat ·inmembership ·len(t)length — each returns a new tuple or a bool/int. - Immutable: no
t[0] = x, noappend, nodel. Build a new tuple from slices to "change" one. - A tuple containing a list can still have its inner list mutated — the tuple's slots are fixed, but the objects in them might not be.
- Unpacking (tuple assignment):
lat, lon = pointsplits a tuple into variables. Functions that "return two things" return a tuple. - Nested tuples work like nested lists — use two indices:
students[1][0]. - Built-in FUNCTIONS:
len, tuple, min, max, sum, sorted, reversed.sorted()returns a list — wrap intuple()to get a tuple. - Only two METHODS:
count(x)andindex(x). - CBSE programs: max/min/mean (built-ins or a single-pass loop), linear search (
for-else), frequency counting (count()onset(t)). - Use a tuple when the data is fixed — coordinates, dates, records — or when you need a dict key / set element. Use a list when the collection will grow, shrink or change.