Tuples: Creating, Indexing and Immutability
Quick answer A tuple is an ordered, indexed collection that cannot be changed after it is created — and the comma, not the bracket, is what actually makes one.
A tuple is an ordered collection of values written inside round brackets and separated by commas. It behaves almost exactly like a list, with one hard difference: once a tuple exists you cannot change it. You cannot replace an item, add an item or delete an item. This property is called immutability.
Why would anyone want a container you cannot edit? Because a lot of real data should not change. The PNR and date of travel on an IRCTC ticket, the (latitude, longitude) of a school, the fixed order of the twelve months, one printed row of a marksheet — if a stray line of code overwrites one of these, the bug is silent and expensive. A tuple simply refuses the edit, so the accident cannot happen.
1. Creating a tuple
marks = (78, 92, 65, 88, 71)
print(marks)
print(type(marks))
empty = ()
print(empty, type(empty), len(empty))
# single element - the classic trap
a = (5)
b = (5,)
print(a, type(a))
print(b, type(b))
print(len(b))
# parentheses are optional
student = "Aarav", 11, "CS"
print(student, type(student))Real output:
(78, 92, 65, 88, 71)
() 0
5
(5,)
1
('Aarav', 11, 'CS') Look hard at lines 4 and 5. (5) is not a tuple — it is just the integer 5 with a pair of ordinary brackets round it, exactly like (2 + 3) in maths. What creates a tuple is the comma, not the bracket. So a one-element tuple must be written (5,). This trailing comma looks like a typing mistake but it is compulsory, and it is asked in the board exam almost every year.
The last line shows the other side of the same rule: because the comma does the work, the brackets can be dropped altogether. "Aarav", 11, "CS" is already a tuple.
2. Indexing
Items are numbered from 0 from the left and from -1 from the right, exactly as in strings and lists.
subjects = ('English', 'Physics', 'Chemistry', 'Maths', 'CS')
print(subjects[0])
print(subjects[4])
print(subjects[-1])
print(subjects[-5])Real output:
English
CS
CS
EnglishAsk for an index that does not exist and the program stops with a run-time error:
subjects = ('English', 'Physics', 'Chemistry', 'Maths', 'CS')
print(subjects[5])Real output:
Traceback (most recent call last):
File "demo.py", line 2, in
print(subjects[5])
~~~~~~~~^^^
IndexError: tuple index out of rangeA tuple of 5 items has valid indexes 0 to 4 and -1 to -5. Anything else is an IndexError.
3. Immutability, shown as an actual error
prices = (250, 499, 120)
prices[0] = 300Real output:
Traceback (most recent call last):
File "demo.py", line 2, in
prices[0] = 300
~~~~~~^^^
TypeError: 'tuple' object does not support item assignmentThe tuple refused the edit and the program stopped. What you can do is build a brand-new tuple out of the old one:
prices = (250, 499, 120)
prices = prices + (999,)
print(prices)Real output:
(250, 499, 120, 999)Learn that error message word for word. And notice what the second program does not do: it does not modify the tuple. prices + (999,) built a brand-new tuple and the name prices was pointed at it. The original object was never touched — it was simply abandoned.
4. The tuple() function
print(tuple("UPI"))
print(tuple([10, 20, 30]))
print(tuple(range(1, 6)))
print(tuple())Real output:
('U', 'P', 'I')
(10, 20, 30)
(1, 2, 3, 4, 5)
()tuple() converts any sequence — a string, a list or a range — into a tuple, and tuple() with nothing inside it gives the empty tuple. A plain number is not a sequence, so there is nothing to convert:
print(tuple(45))Real output:
Traceback (most recent call last):
File "demo.py", line 1, in
print(tuple(45))
~~~~~^^^^
TypeError: 'int' object is not iterable5. Nested tuples
A tuple can hold other tuples. This is how you store a table — one inner tuple per row.
result = (('Aarav', 87), ('Diya', 91), ('Kabir', 78))
print(result[1])
print(result[1][0])
print(result[1][1])
print(len(result))
# a mutable object inside an immutable tuple
t = (1, [2, 3], 4)
t[1].append(99)
print(t)Real output:
('Diya', 91)
Diya
91
3
(1, [2, 3, 99], 4)Changing what is inside the list worked. Swapping the list itself for a different object is still blocked:
t = (1, [2, 3], 4)
t[1] = [7, 8]Real output:
Traceback (most recent call last):
File "demo.py", line 2, in
t[1] = [7, 8]
~^^^
TypeError: 'tuple' object does not support item assignmentlen(result) is 3, not 6 — len() counts only the top level. The t = (1, [2, 3], 4) half is a favourite trick question. The tuple t is immutable, but the list stored inside it is not. You cannot swap the list for a different object, yet you can change the contents of that list. The tuple only promises "the same three objects, in this order, forever" — it makes no promise about what is inside those objects.
6. List versus tuple
| Point | List | Tuple |
|---|---|---|
| Brackets | [ ] | ( ) |
| Changeable | Yes (mutable) | No (immutable) |
| append / remove / sort | Available | Not available |
| Methods | Exactly 11 | Only 2: count(), index() |
| Can be a dictionary key | No | Yes |
| Use it for | Data that grows or changes | Fixed records and constants |
- The comma makes a tuple, not the brackets: (5) is an int, (5,) is a one-item tuple, and x = 1, 2 is a tuple with no brackets at all.
- Assigning to an item gives TypeError: 'tuple' object does not support item assignment. Building a new tuple with + is allowed because it does not modify the old one.
- Indexes run 0 to n-1 and -1 to -n; anything outside gives IndexError: tuple index out of range.
- len() counts only the top level of a nested tuple, so len((('a',1),('b',2))) is 2.
- A list stored inside a tuple can still be modified — the tuple freezes which objects it holds, not what is inside them.
