
Python Course
Tuples in Python
In the previous lesson you learned about lists — ordered collections you can change freely. Python also has a second type of ordered collection called a tuple. The key difference is that once you create a tuple, you cannot change it. This property is called immutability.
This might sound like a limitation, but it is actually a feature. When you use a tuple, you are sending a clear message to yourself and every other developer reading your code: this data is fixed and should never be accidentally modified. Tuples are used in professional Python programs constantly — for coordinates, settings, database records, dictionary keys, and function return values.
Creating a Tuple
Tuples are created using round brackets () with items separated by commas. You can store any type of data inside a tuple — numbers, text, booleans, or a mix.
cities = ("Mumbai", "Delhi", "Bangalore", "Chennai")
temperatures = (36.5, 37.0, 35.8, 38.2)
employee_record = ("E1042", "Software Engineer", 85000, True)
print(cities)
print(temperatures)
print(employee_record)
- Round brackets
()define a tuple. Python always prints tuples with parentheses around them. - A tuple can hold values of different types in the same collection.
- Common uses: GPS coordinates, RGB colour values, database rows, fixed configuration settings.
The Singleton Tuple — One Item
This is one of the most common beginner mistakes. If you write a single value inside brackets without a trailing comma, Python does NOT create a tuple — it treats the brackets as just grouping syntax.
# NOT a tuple — Python ignores the brackets
not_a_tuple = ("Python")
print(type(not_a_tuple)) # str
# IS a tuple — the trailing comma makes it one
single_item = ("Python",)
print(type(single_item)) # tuple
- Always add a trailing comma when creating a single-item tuple:
("value",) - Without the comma, Python simply treats the brackets as grouping, not as a tuple.
Accessing Tuple Elements
Tuples are indexed starting from 0, exactly like lists. You access items using square brackets with the index number. Negative indexing works the same way too.
languages = ("Python", "Java", "C++", "JavaScript", "Go")
print(languages[0]) # first element
print(languages[2]) # third element
print(languages[-1]) # last element
print(languages[-2]) # second from last
Tuple Slicing
You can extract a portion of a tuple using the same slicing syntax as lists. The result is a new tuple — the original is untouched.
months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
q1 = months[0:3] # first quarter
q2 = months[3:6] # second quarter
last_four = months[8:] # last four months
alternate = months[0:12:2] # every other month
reversed_m = months[::-1] # reversed
print("Q1:", q1)
print("Q2:", q2)
print("Last four:", last_four)
print("Alternate:", alternate)
- The stop index is always excluded.
months[::-1]reverses the entire tuple in one step — a very common Python pattern.
Tuple Immutability
The most important thing to understand about tuples is that you cannot change them after creation. If you try to assign a new value to an index, or call append(), Python will raise an error immediately.
coordinates = (28.6139, 77.2090)
# Trying to change an element raises TypeError
try:
coordinates[0] = 19.0760
except TypeError as e:
print("Error:", e)
# Trying to append raises AttributeError
try:
coordinates.append(100)
except AttributeError as e:
print("Error:", e)
print("Original unchanged:", coordinates)
- Tuples have no
append(),remove(), orinsert()methods because they cannot change. - This protection is exactly what makes tuples useful for fixed data — accidental changes are impossible.
Tuple Packing and Unpacking
Packing means collecting multiple values into one tuple. Unpacking means extracting those values back into separate variables in a single clean step. This is one of the most elegant and widely used Python features.
# Packing — combining values into a tuple
product = ("Laptop", "Electronics", 75000, True)
print("Packed:", product)
# Unpacking — one variable per element
name, category, price, in_stock = product
print("Name:", name)
print("Price:", price)
# Star unpacking — capture remaining items
scores = (92, 87, 95, 78, 88)
first, second, *remaining = scores
print("First:", first)
print("Remaining:", remaining)
- The number of variables on the left must match the number of tuple elements, unless you use
*. - The
*operator captures all remaining elements into a list. - Unpacking is used constantly when functions return multiple values.
Tuple Methods
Because tuples are immutable, they have only two built-in methods: count() and index().
grades = (85, 92, 78, 85, 90, 85, 72, 92)
# count() — how many times a value appears
print("Count of 85:", grades.count(85)) # 3
print("Count of 92:", grades.count(92)) # 2
# index() — first position where value is found
print("Position of 78:", grades.index(78)) # 2
print("Position of 92:", grades.index(92)) # 1
Tuple Operations
Even though tuples cannot be changed, you can perform operations on them that produce new tuples.
frontend = ("HTML", "CSS", "JavaScript")
backend = ("Python", "SQL", "Django")
# Concatenation — joining two tuples
full_stack = frontend + backend
print("Full Stack:", full_stack)
# Repetition — repeating a tuple
warning = ("Check input!",)
print("Repeated:", warning * 3)
# Membership check
print("Python in full_stack?", "Python" in full_stack)
print("PHP in full_stack?", "PHP" in full_stack)
# Length
print("Total skills:", len(full_stack))
Nested Tuples
A tuple can contain other tuples as its elements. This is commonly used to represent rows of structured data — like a table of employee records or database query results.
employees = (
("E101", "Ananya", "Developer", 90000),
("E102", "Rajan", "Designer", 75000),
("E103", "Suman", "Manager", 110000)
)
print("Second employee:", employees[1])
print("Name of first:", employees[0][1])
print("Salary of third:", employees[2][3])
for emp in employees:
print(f" {emp[0]} | {emp[1]} | {emp[2]} | {emp[3]}")
employees[1]accesses the entire second inner tuple.employees[0][1]uses double indexing — first access the outer tuple's item, then access an item inside that.
Looping Through a Tuple
Looping through a tuple works exactly like looping through a list. You can also use enumerate() to get both the index and value.
tasks = ("Design UI", "Write Backend", "Set up Database", "Test", "Deploy")
# Basic loop
for task in tasks:
print("-", task)
# Loop with position numbers
for index, task in enumerate(tasks, start=1):
print(f" {index}. {task}")
Converting Between Tuples and Lists
If you need to modify a tuple, convert it to a list, make your changes, then convert it back. This is the standard approach in Python.
colour_codes = ("#FF5733", "#28B463", "#2E86C1")
# Convert to list to modify
colour_list = list(colour_codes)
colour_list.append("#F39C12")
colour_list[0] = "#E74C3C"
# Convert back to tuple
colour_codes = tuple(colour_list)
print("Updated tuple:", colour_codes)
# Convert a list to tuple
raw_data = [10, 20, 30, 40, 50]
fixed_data = tuple(raw_data)
print("As tuple:", fixed_data)
Tuples as Dictionary Keys
One unique ability tuples have that lists do not — tuples can be used as dictionary keys. This works because tuples are immutable (their value never changes), which is required for dictionary keys. Lists cannot be used as keys.
# Using (latitude, longitude) tuples as dictionary keys
location_map = {
(28.6139, 77.2090): "New Delhi",
(19.0760, 72.8777): "Mumbai",
(12.9716, 77.5946): "Bangalore"
}
search = (19.0760, 72.8777)
print("City at", search, ":", location_map[search])
- Using a list as a key would raise
TypeError: unhashable type: 'list'. - Tuple keys are used in geographic systems, game grids, and caching layers.
Tuples vs Lists — When to Use Each
Use a tuple when the data is fixed and should not change — coordinates, RGB values, database records, days of the week. Use a list when the data is dynamic and will change — shopping carts, task queues, user inputs.
Tuples also use slightly less memory and are created faster than lists, which matters in large-scale programs processing millions of records.
Quick Reference Table
| Concept | Syntax | Key Point |
|---|---|---|
| Create tuple | t = (1, 2, 3) | Ordered, immutable |
| Singleton tuple | t = (5,) | Trailing comma required |
| Index access | t[0], t[-1] | Starts at 0, -1 is last |
| Slicing | t[1:4], t[::-1] | Stop index excluded |
| Immutability | t[0] = 5 → TypeError | Cannot modify elements |
| Unpacking | a, b, c = t | Variables must match count |
| Star unpacking | a, *rest = t | Rest becomes a list |
| count() | t.count(5) | How many times value appears |
| index() | t.index(5) | First position of value |
| Concatenation | t1 + t2 | Creates a new tuple |
| Membership | x in t | Returns True or False |
| Convert to list | list(t) | Use to modify, then convert back |
| Convert to tuple | tuple(lst) | Makes list immutable |
| As dict key | d[(1,2)] = "val" | Tuples are hashable |
Practice
A tuple cannot be changed after creation. What word describes this property?
What index is used to access the last element of a tuple using negative indexing?
Which tuple method counts how many times a value appears?
To modify the contents of a tuple, you should first convert it to a what?
Quick Quiz
What error does Python raise when you try to change an element of a tuple?
Can a tuple be used as a dictionary key in Python?
Given t = (10, 20, 30, 40, 50), what does t.index(40) return?
What is the output of (1, 2, 3) * 2?