Free Study Material
Lists are mutable — they can change after creation. This chapter covers a collection type that looks similar but deliberately can't: the tuple.
A tuple is an ordered, immutable collection, written inside round brackets (), separated by commas. Once created, a tuple's elements can never be added, removed, or changed — the entire tuple can only be replaced by assigning a brand-new one.
marks = (78, 85, 92)
A tuple with exactly one element needs a trailing comma — without it, Python treats the brackets as ordinary parentheses around a single value, not a tuple at all.
coordinates = (10, 20)
single = (5,)
not_a_tuple = (5)
print(type(coordinates))
print(type(single))
print(type(not_a_tuple))
print(coordinates[0])
print(coordinates[-1])
type(coordinates) and type(single) both print <class 'tuple'>. type(not_a_tuple) prints <class 'int'> — with no comma, (5) is just the integer 5 wrapped in ordinary parentheses. Accessing elements uses the exact same indexing rules as lists and strings: coordinates[0] gives 10, coordinates[-1] gives 20.
Warning:single = (5)(no comma) is a common mistake when a tuple needs exactly one element — Python only recognizes it as a tuple with the trailing comma present,(5,).
A tuple is the right choice specifically when a collection's values should never change once created — coordinates, a fixed set of days in a week, a record that represents a completed, unchangeable fact. Using a tuple instead of a list for such data is a genuine safeguard: any attempted modification raises an error immediately, rather than silently succeeding and introducing a bug elsewhere.
A tuple is an ordered, immutable collection written in round brackets — indexed and sliced exactly like a list or string, but never changeable after creation. A single-element tuple needs a trailing comma, (value,), or Python doesn't treat it as a tuple at all.
A Tuple is an ordered collection of items enclosed in Parentheses ( ).
Once a tuple is created, you cannot change, add, or remove items from it. It is "Read-Only" data.
Examples:
t = ()nums = (10, 20, 30)record = ("Amit", 101, 95.5)t = tuple("ABC") → ('A', 'B', 'C')If you want to create a tuple with only ONE item, you MUST put a comma after it.
# 1. Standard Tuple
colors = ("Red", "Green", "Blue")
print("Colors:", colors)
# 2. The Trap (Single Item)
not_a_tuple = ("Hello")
is_a_tuple = ("Hello",)
print("Type 1:", type(not_a_tuple)) # <class 'str'>
print("Type 2:", type(is_a_tuple)) # <class 'tuple'>
data = (10, 20, 30, 40, 50)
# Indexing
print("First:", data[0]) # 10
print("Last:", data[-1]) # 50
# Slicing
# From index 1 to 3 (Excluded)
print("Slice:", data[1:3]) # (20, 30)
t = (1, 2, 3)
# Try to change the first item
# Uncommenting the next line will cause an Error!
# t[0] = 99
# Error: 'tuple' object does not support item assignment
print("If you see this, the tuple remained safe.")
Since a tuple is still an ordered collection, it supports the same general operators and traversal pattern as lists and strings — just without anything that would change it.
+) — joins two tuples into a new tuple.*) — repeats a tuple's elements a given number of times.in / not in) — checks whether a value exists inside a tuple.my_tuple[a:b], same rules as a list, and also returns a tuple.for loop.days_a = ("Mon", "Tue", "Wed")
days_b = ("Thu", "Fri")
print(days_a + days_b)
print(days_a * 2)
print(len(days_a))
print("Wed" in days_a)
print(days_a[0:2])
for day in days_a:
print("Day:", day)
days_a + days_b gives a new tuple, ('Mon', 'Tue', 'Wed', 'Thu', 'Fri') — the originals are untouched. days_a * 2 gives ('Mon', 'Tue', 'Wed', 'Mon', 'Tue', 'Wed'). len(days_a) is 3. "Wed" in days_a is True. days_a[0:2] gives the tuple ('Mon', 'Tue') — slicing a tuple returns another tuple, not a list. The for loop then traverses all three elements of days_a, one per line.
Note: Every one of these operations produces a new tuple (or, forin/len, a plain value) — none of them modifydays_aordays_bthemselves. There is no operation that could, since tuples are immutable.
Every operator here behaves exactly like its list counterpart from the previous chapter, with one consistent difference: nothing ever changes the original tuple in place, because nothing is allowed to — this mirrors exactly how string operators worked, for the same underlying reason (immutability).
Tuples support +, *, in/not in, len(), and slicing — all identical in behaviour to lists, except every result is a brand-new tuple (or plain value), since a tuple itself can never be changed in place. for element in my_tuple: traverses every element in order.
Joins two tuples together to create a new one.
Repeats the tuple elements a specific number of times.
# 1. Concatenation
t1 = (1, 2)
t2 = (3, 4)
# This creates a NEW tuple 't3'
t3 = t1 + t2
print("Joined:", t3) # (1, 2, 3, 4)
print("Original t1:", t1) # (1, 2) - Unchanged!
# 2. Repetition
t4 = ("No",) * 3
print("Repeated:", t4) # ('No', 'No', 'No')
# Check if an item exists
menu = ("Pizza", "Burger", "Coke")
if "Pizza" in menu:
print("Ordering Pizza!")
if "Salad" not in menu:
print("No salad available.")
In Lists, we often use range(len(L)) to update values (e.g., L[i] = 5).
In Tuples, this will cause an error because tuples are Read-Only. Therefore, looping by element is usually preferred.
# Standard Traversal
# Just reading the data
coordinates = (10, 20, 30)
print("--- Points ---")
for point in coordinates:
print("Value:", point)
# Index Traversal
names = ("Alice", "Bob")
n = len(names)
for i in range(n):
print("Index:", i, "Name:", names[i])
# names[i] = "Charlie" <-- THIS WOULD CRASH
Tuples support the same summarising functions as lists, plus exactly two methods of their own — a much shorter list than a list's, and directly a consequence of being immutable.
value occurs.value's first occurrence; raises ValueError if it's missing.A tuple has only these two methods. There is no append(), insert(), remove(), pop(), or sort() for a tuple — every one of those would need to change the tuple in place, which immutability doesn't allow.
marks = (67, 92, 45, 88, 67)
print(len(marks))
print(min(marks))
print(max(marks))
print(sum(marks))
print(sorted(marks))
print(marks.count(67))
print(marks.index(88))
len(marks) is 5. min(marks) is 45; max(marks) is 92. sum(marks) is 359. sorted(marks) returns [45, 67, 67, 88, 92] — notice the square brackets: the result is a list, even though the input was a tuple. marks.count(67) returns 2 (it occurs twice). marks.index(88) returns 3 (its position).
Warning:marks.append(100)raisesAttributeError: 'tuple' object has no attribute 'append'— this error is Python confirming, directly, that tuples are immutable: the method to change one in place simply does not exist.
sorted() returning a list rather than a tuple is worth noticing precisely because it's easy to assume otherwise: sorted() always builds a brand-new collection, and that new collection's type is a list regardless of what kind of collection was passed in.
Tuples support len(), min(), max(), sum(), and sorted() (which returns a list) exactly like lists do, but have only two methods of their own — count() and index() — since every method that would modify a tuple in place doesn't exist at all, a direct consequence of immutability.
# The only two methods
t = (10, 20, 10, 30, 10)
# 1. count()
print("Count of 10:", t.count(10)) # Output: 3
# 2. index()
print("Index of 20:", t.index(20)) # Output: 1
# Warning: t.index(99) would crash if 99 isn't there!
len(t)
Returns total items.
sum(t)
Returns total sum (Numbers only).
min(t)
Returns smallest value.
max(t)
Returns largest value.
# The Sorting Trap
data = (3, 1, 2)
# 1. Try to use .sort() -> ERROR
# data.sort() <-- AttributeError: 'tuple' object has no attribute 'sort'
# 2. Use sorted() -> SUCCESS (Returns a List)
new_data = sorted(data)
print("Original Tuple:", data) # (3, 1, 2) - Safe
print("Sorted Result:", new_data) # [1, 2, 3] - It's a LIST!
print("Type:", type(new_data)) # <class 'list'>
# Convert List to Tuple
shopping_list = ["Bread", "Milk"] # Mutable
frozen_list = tuple(shopping_list) # Immutable
print(frozen_list) # ('Bread', 'Milk')
Tuples support one convenient pattern lists rarely use this way: unpacking several values out of a tuple into separate variables in a single line. This topic covers that, plus tuples that contain other tuples.
a, b, c = (10, 20, 30)
Each variable on the left receives the value at the matching position on the right, in one statement. The number of variables must match the number of values exactly, or Python raises a ValueError.
Like a nested list, a tuple can contain other tuples as elements, read with two indexes: outer[i][j].
point = (10, 20)
x, y = point
print(x)
print(y)
name, age, marks = ("Rahul", 16, 78)
print(name, "is", age, "years old, scored", marks)
student = ("Aisha", (91, 85, 88))
print(student[0])
print(student[1][0])
x, y = point unpacks point's two values directly into x and y, so x is 10 and y is 20 — no indexing needed. The same pattern unpacks ("Rahul", 16, 78) into three separate variables in one line. student is a tuple whose second element is itself a tuple of three marks — student[0] reaches "Aisha", and student[1][0] reaches inside the nested tuple to its first mark, 91.
Warning:x, y, z = point(three variables, butpointonly has two values) raisesValueError: not enough values to unpack (expected 3, got 2)— the count on both sides of a tuple assignment must match exactly.
Tuple assignment isn't just shorter to write — it's also how Python performs a clean swap between two variables in a single line: a, b = b, a works because Python builds the tuple (b, a) on the right-hand side completely, before unpacking it back into a, b — this is worth remembering, since it comes up constantly in later programs.
Tuple assignment (a, b, c = my_tuple) unpacks a tuple's values into separate variables in one line, and requires an exact count match on both sides. A nested tuple contains other tuples as elements, read with two indexes (outer[i][j]), exactly like a nested list.
The Rule: You must have exactly one variable for every item.
If the tuple has 3 items, you need 3 variables. If you have 2 or 4, Python raises a ValueError.
# 1. Standard Assignment
coordinates = (10, 20)
# Unpacking: Extract x and y
(x, y) = coordinates
print("X value:", x) # Output: 10
print("Y value:", y) # Output: 20
# 2. The Magic Trick: Swapping Variables
# In other languages, you need a temporary variable (temp = a; a = b; b = temp)
# In Python, we use tuple assignment:
a = 5
b = 10
(a, b) = (b, a)
print("a is now:", a) # Output: 10
print("b is now:", b) # Output: 5
# A tuple storing student records (Name, Roll No, Marks)
students = (
("Amit", 1, 95), # Index 0
("Neha", 2, 88), # Index 1
("Raj", 3, 92) # Index 2
)
# 1. Accessing a whole record
print("Second Student:", students[1])
# Output: ('Neha', 2, 88)
# 2. Accessing specific data (Neha's Marks)
# Go to Index 1 (Neha), then Index 2 (Marks)
print("Neha's Marks:", students[1][2])
# Output: 88
# 3. Traversal (Looping)
print("--- Class List ---")
for record in students:
# record is ('Amit', 1, 95)
print("Name:", record[0], "Marks:", record[2])
This closing topic puts the whole chapter to work — creation, traversal, built-in functions, and unpacking — in two small, complete programs.
marks = (78, 85, 92, 67, 74)
total = 0
for value in marks:
total = total + value
average = total / len(marks)
print("Total:", total)
print("Average:", average)
The loop traverses marks and builds up total one value at a time — the same running-total pattern from the Iterative Statements chapter, applied to a tuple instead of a range of numbers. total becomes 78 + 85 + 92 + 67 + 74 = 396, and average is 396 / 5 = 79.2.
a = 10
b = 25
print("Before swap:", a, b)
a, b = b, a
print("After swap:", a, b)
Before the swap, a is 10 and b is 25. a, b = b, a builds the tuple (25, 10) from the current values first, then unpacks it back into a and b in one step — so a becomes 25 and b becomes 10, without needing any separate temporary variable.
Tip: A three-line swap using a temporary variable (temp = a,a = b,b = temp) does exactly the same thing —a, b = b, ais simply Python's shorter, built-in way of writing it, made possible entirely by tuple assignment.
Both programs reuse patterns from earlier in this unit — a running total inside a loop, and tuple unpacking from the last topic — combined here to solve two small, complete problems, exactly the kind of two-or-three-line question this chapter is tested with.
Averaging a tuple's values combines traversal with a running total, exactly like summing a range of numbers in a loop. Swapping two variables in one line, a, b = b, a, relies entirely on tuple assignment — Python builds the right-hand tuple first, then unpacks it, with no temporary variable needed.
To find the biggest (or smallest) number manually, we follow these steps:
# Program: Find Min, Max, and Mean manually
data = (45, 88, 12, 67, 99, 34)
# 1. Initialization (Assume first item is the baseline)
current_min = data[0]
current_max = data[0]
total_sum = 0
n = len(data)
# 2. Traversal
for num in data:
# Add to total for Average calculation later
total_sum = total_sum + num
# Check for new Max
if num > current_max:
current_max = num
# Check for new Min
if num < current_min:
current_min = num
# 3. Final Calculation
average = total_sum / n
print("Tuple Data:", data)
print("Maximum Value:", current_max)
print("Minimum Value:", current_min)
print("Average (Mean):", average)
We need to find where a specific number is located.
found = False) to remember if we succeed.found = True, and immediately STOP the loop using break. (No need to keep searching!)# Program: Linear Search in a Tuple
numbers = (10, 50, 30, 70, 80, 20)
target = 70
found = False # Step 1: Initialize Flag
# Step 2: Loop using Index
for i in range(len(numbers)):
if numbers[i] == target:
print("Success! Found", target, "at Index:", i)
found = True
break # Step 3: Stop searching
# Step 4: Check Flag
if found == False:
print("Sorry,", target, "is not in the tuple.")
This is a simple accumulation logic.
# Program: Count Frequency Manually
votes = ("A", "B", "A", "C", "A", "B")
candidate = "A"
count = 0
for vote in votes:
if vote == candidate:
count = count + 1
print("Candidate", candidate, "received", count, "votes.")
A working recap of this chapter, tying together creation, access, the built-in functions and methods, and unpacking, in one continuous program.
(value1, value2, ...) — ordered, immutable. A single-element tuple needs a trailing comma: (value,).count() and index().len(), min(), max(), sum(), sorted() (returns a list).a, b, c = my_tuple — matching count required on both sides.record = ("Rahul", 78, 85, 92)
name = record[0]
scores = record[1:]
print("Name:", name)
print("Scores:", scores)
print("Highest:", max(scores))
print("Total:", sum(scores))
subject, first, second, third = record
print(subject, "scored", first, ",", second, ",", third)
record[0] reaches "Rahul"; record[1:] slices out everything from index 1 onward, itself a tuple, (78, 85, 92). max(scores) is 92; sum(scores) is 255. The final line unpacks record's four values directly into subject, first, second, and third in one statement — the same tuple-assignment pattern from earlier in this chapter, now applied to a four-element tuple instead of two or three.
Tip:record[1:](a slice) andrecord[1](a single index) look similar but return very different things — a slice always returns a tuple (even one with a single element), while a plain index returns the raw value at that one position.
A tuple is created with ( ), immutable once made, read with the same indexing/slicing rules as a list, summarised with len()/min()/max()/sum()/sorted(), searched with only count()/index(), and can have all of its values unpacked into separate variables in one line — the full toolkit this chapter covered, working together on one tuple.
A Tuple is an ordered collection of items enclosed in Parentheses ( ). Like a list, it can store mixed data types, but it is fundamentally different in one way:
Once created, you CANNOT change, add, or remove items. (No append, No sort, No assignment like t[0]=5).
Items are indexed starting from 0 (Left to Right) and -1 (Right to Left).
| Type | Code | Note |
| Empty | t = () | - |
| Single Item | t = (5,) | MUST have a comma! (5) is just a number. |
| Standard | t = (1, 2) | Comma separates items. |
| Constructor | t = tuple(L) | Converts a List `L` to a Tuple. |
| Category | Code | Explanation |
|---|---|---|
| Methods | T.count(x) |
Returns how many times `x` appears. |
T.index(x) |
Returns index of first `x`. (Error if missing). | |
| Math Ops | T1 + T2 |
Concatenation: Joins two tuples into a NEW one. |
T * 3 |
Repetition: Repeats tuple items 3 times. | |
x in T |
Membership: Returns True if `x` is in `T`. | |
| Functions | len(T) |
Returns the total number of items. |
sorted(T) |
CRITICAL: Returns a sorted LIST `[]`. | |
min/max(T) |
Returns the smallest/largest value. |
coordinates = (10, 20)
x, y = coordinates # x=10, y=20
# T = ( (1, 2), (3, 4) )
val = T[1][0] # First selects index 1 -> (3, 4), then index 0 -> 3
| Feature | List [ ] | Tuple ( ) |
|---|---|---|
| Mutability |
Mutable (Changeable) Can add, delete, or change items. |
Immutable (Read-Only) Cannot change once created. |
| Performance |
Slower Requires extra memory for operations. |
Faster Simple structure, less memory overhead. |
| Methods |
Many Built-in Methodsappend
extend
pop
remove
sort
|
Only Two Methodscount
index
|
| Best For... |
Collections that change often. (e.g., Shopping carts, To-Do lists) |
Data that must not change. (e.g., Coordinates, Config settings, Database keys) |