AI Computer Institute
Expert-curated CS & AI curriculum aligned to CBSE standards. A bharath.ai initiative. About Us

Sets and Tuples: Immutable and Unique Collections

📚 Python Mastery⏱️ 21 min read🎓 Grade 8
✍️ AI Computer Institute Editorial Team Updated: August 2026 CBSE-aligned · Peer-reviewed · 21 min read
Content curated by subject matter experts with IIT/NIT backgrounds. All chapters are fact-checked against official CBSE/NCERT syllabi.

Open the SMS or app notification you get after booking an IRCTC ticket. It reads something like: PNR 4567891234, train 12951, from New Delhi to Mumbai Central, coach B4, seat 32, date 18-Jul-2026. Six pieces of information, glued together in one exact order. If the railways could quietly rearrange this to seat 32, coach B4, 12951, New Delhi... you'd still technically have "the same information," but you'd have no idea which number was your seat and which was your train number. The order is not decoration here — it is part of the meaning. And critically, once that ticket is issued, nobody is allowed to sneak in and change your seat number without cancelling and rebooking. The record is locked.

Now think about something else from your own school life: the list of roll numbers of students who submitted a lab file on time. If three different monitors independently note down who submitted — 12, 7, 19, 12, 23, 7 — you don't actually care that roll number 12 got written down twice by two careless monitors. What you care about is: which distinct students submitted? The answer is a group of five students, not six entries. Order doesn't matter here either — "7, 12, 19, 23" and "23, 19, 12, 7" describe the exact same group of submitters. What matters is that each member appears once, and it's exactly clear who belongs and who doesn't.

These two situations are the entire chapter in miniature. The IRCTC ticket is crying out to be modeled as a tuple: an ordered sequence of values that, once created, cannot be changed. The submission roster is crying out to be modeled as a set: an unordered collection where every value is guaranteed to appear at most once. Python gives you both as first-class, ready-to-use data types, and knowing exactly when to reach for each one is a skill that separates a programmer who merely gets code to run from one who writes code that says what it means.

Tuples: Sequences That Cannot Change

You already know Python lists — ordered collections you build with square brackets, like marks = [78, 85, 90], and can freely edit with marks.append(88) or marks[0] = 80. A tuple looks almost identical but is built with round brackets, and it refuses every attempt to edit it after creation. Let's build the IRCTC ticket as one:

ticket = ("4567891234", "New Delhi", "Mumbai", "B4", 32)
print(ticket)
print(type(ticket))

Trace it line by line. Line 1 creates a tuple of five values — three strings, one more string, one integer — and binds the name ticket to it. Line 2 prints the tuple exactly as Python stores it, so the output is:

('4567891234', 'New Delhi', 'Mumbai', 'B4', 32)
<class 'tuple'>

Just like lists, tuples support indexing and slicing, because a tuple is still an ordered sequence — position has meaning. ticket[0] gives you '4567891234', and ticket[-1] gives you 32 (negative indices count from the end, same rule as lists and strings). A slice like ticket[1:3] gives you ('New Delhi', 'Mumbai') — a new, smaller tuple containing the source and destination, since slicing stops before index 3.

Now the defining moment. Try to change the coach:

ticket[3] = "B5"

This raises TypeError: 'tuple' object does not support item assignment. Python is not being difficult for no reason — it is enforcing the exact real-world rule you already understood intuitively: this record was issued, and issued records don't get silently edited. If you genuinely need a different ticket, you build a brand-new tuple; you never mutate the old one.

Packing, Unpacking, and the One-Element Trap

Writing ticket = ("4567891234", "New Delhi", "Mumbai", "B4", 32) is called packing — five separate values are packed into one tuple. Python also lets you go the other direction, unpacking, where a tuple's values are handed out to separate variable names in one line:

pnr, source, destination, coach, seat = ticket
print(coach, seat)

This works because Python matches positions: the first name gets the first value, and so on. Since there are exactly five names for five values, this runs cleanly and prints B4 32. If you wrote only four names on the left, Python would raise ValueError: too many values to unpack — the count must match exactly, unless you deliberately use a starred name like *rest to soak up the extras, which is a technique for later.

Here is a misconception that trips up almost every beginner, and it is worth fixing permanently right now: it is the comma that makes a tuple, not the parentheses. Watch this carefully:

x = (5)
y = (5,)
print(type(x))
print(type(y))

You might expect both to be tuples, since both use round brackets. But the output is:

<class 'int'>
<class 'tuple'>

(5) is just the number 5 sitting inside ordinary grouping parentheses, the same parentheses you use in arithmetic like (2 + 3) * 4. Python only recognizes a tuple when it sees a comma. (5,) — with that trailing comma — is a genuine one-element tuple. This is precisely why, when you write a tuple with more than one item, the parentheses feel essential but are actually optional: ticket = "4567891234", "New Delhi", "Mumbai", "B4", 32 creates the identical tuple as before, because the commas alone did the work. Parentheses are added purely for readability and to remove ambiguity in more complex lines — they are not what defines a tuple. On a CBSE paper, if you're asked to identify the type of t = (10), the correct answer is "int," and this single trap accounts for a surprising number of lost marks.

Why Bother With Immutability?

A fair question: if a list can do everything a tuple does, plus let you edit it, why would anyone choose the more restrictive option? Three real reasons. First, a tuple communicates intent — when you see a tuple in someone's code, you instantly know "this data is not meant to change," which makes the code easier to reason about without reading every line that touches it. Second, because tuples can never change, Python can use them in places that require a fixed, unchanging value — specifically as keys in a dictionary or as members of a set, something a list is never allowed to be, as you'll see in a moment. Third, tuples are commonly used as the natural return type when a function needs to hand back several related values at once — for instance a function that computes both the average and the highest mark from a test would naturally return average, highest, which Python packs into a tuple automatically.

Sets: Collections Where Every Member Is Unique

Return to the attendance example. Three monitors record who submitted a lab file, and their combined notes contain a duplicate:

submitted = {12, 7, 19, 12, 23, 7}
print(submitted)
print(len(submitted))

Curly braces with comma-separated values create a set. When Python builds this set, it silently drops every repeat — a set can never contain the same value twice, by definition, not by accident. The output will contain the four distinct values 7, 12, 19, 23 — for example {7, 12, 19, 23} — and len(submitted) prints 4, not 6. Notice something important: I wrote "for example" about the printed order. Python does not promise you any particular order when it displays a set, and for a set of general-purpose values you should never write code that depends on one particular order appearing.

Checking whether someone is in the set is fast and reads like English: 103 in submitted evaluates to False, while 12 in submitted evaluates to True. This membership test is one of the biggest reasons to use a set over a list: for a list of a thousand roll numbers, checking membership means Python may have to look through all thousand one by one, but a set is built internally (using a technique called hashing) so that checking membership takes roughly the same tiny amount of time whether the set holds ten items or ten million.

Unlike tuples, sets are mutable — you can add and remove members after creation, using submitted.add(30) or submitted.discard(7). What a set will never let you do is hold a duplicate: calling submitted.add(12) when 12 is already present simply does nothing, silently, because 12 is already a member.

Set Operations: Comparing Two Groups at Once

Sets become genuinely powerful when you compare two of them. Suppose your school records which players featured in two different cricket matches, listing only five names per side to keep the example manageable:

match1 = {"Rohit", "Virat", "Bumrah", "Jadeja", "Pant"}
match2 = {"Rohit", "Virat", "Shami", "Jadeja", "Iyer"}

Four questions a coach might genuinely ask map directly onto four set operations:

print(match1 | match2)   # union
print(match1 & match2)   # intersection
print(match1 - match2)   # difference
print(match1 ^ match2)   # symmetric difference

match1 | match2 is the union — everyone who played at least one of the two matches. Combine both sets and drop duplicates: Rohit, Virat, Bumrah, Jadeja, Pant, Shami, Iyer — seven names in total, since Rohit, Virat, and Jadeja are shared and counted only once.

match1 & match2 is the intersection — only the names present in both sets: {'Rohit', 'Virat', 'Jadeja'}, the three players who turned out for both matches.

match1 - match2 is the difference — everyone in match1 who is not in match2: {'Bumrah', 'Pant'}. Note that difference is directional: match2 - match1 instead gives {'Shami', 'Iyer'}, the players who appeared only in match 2. Order of the operands changes the answer, which is worth pointing out explicitly since union and intersection don't have this property but difference does.

match1 ^ match2 is the symmetric difference — everyone who played exactly one of the two matches, excluding anyone who played both: {'Bumrah', 'Pant', 'Shami', 'Iyer'}, four names.

The diagram below lays out exactly this scenario as a Venn diagram alongside the locked tuple structure, so you can see both ideas of this chapter side by side.

Tuple: Fixed Order, Locked 🔒 '4567891234' (PNR) 'New Delhi' (source) 'Mumbai' (dest.) 'B4' (coach) 32 (seat) index 0 index 1 index 2 index 3 index 4 position always increases left to right ticket = ('4567891234','New Delhi','Mumbai','B4',32) ticket[3] = 'B5' TypeError: tuple does not support item assignment Sets: Two Playing XIs Compared match1 match2 Bumrah Pant Rohit Virat Jadeja Shami Iyer ∪ union: all 7 players who featured in either match ∩ intersection: Rohit, Virat, Jadeja (played both) match1 − match2: Bumrah, Pant (only match 1)

Do Sets Remember the Order You Typed Things?

Here is a second misconception worth stopping on. A set of small non-negative integers, like {7, 12, 19, 23}, often prints back in ascending order, and this seduces many students into believing "sets keep things sorted" or "sets remember insertion order like lists do." Neither is true. What's actually happening is an accident of implementation: Python's set stores integers using a hash table, and for small non-negative integers the built-in hash of a number is simply the number itself, which happens to line the slots up in a way that often looks sorted. The moment you build a set of strings instead, the illusion disappears:

subjects = {"Physics", "Hindi", "Computer Science", "English"}
print(subjects)

The printed order here is not alphabetical, not insertion order, and — because Python randomizes string hashing as a security measure — it can even come out in a different order the next time you run the exact same program. The only correct mental model is: a set has no order at all. If you need your unique values sorted, convert explicitly with sorted(subjects), which returns a list, or if you need to remember the order things were first added, a set is the wrong tool entirely — reach for a list (with manual duplicate-checking) or, in more advanced work, a dictionary.

A closely related trap: {} does not create an empty set — it creates an empty dictionary. type({}) prints <class 'dict'>. To get an empty set you must write set(). This one-character ambiguity exists because curly braces were already claimed by dictionaries before sets were added to the language, and Python chose not to make empty braces mean two different things depending on context — so the empty case defaults to dict, and you must be explicit for an empty set.

Where Tuples and Sets Depend on Each Other

Now for the connection that ties this whole chapter together. A set can only contain values that are hashable — meaning Python can compute a fixed identifying number for that value that will never change for as long as the value exists. Numbers, strings, and tuples are hashable, because none of them can be edited in place. Lists are not hashable, precisely because they can be edited in place — if Python let a list sit inside a set and you then changed that list, the set's internal bookkeeping would be instantly wrong, with no way to fix it. So Python refuses the possibility entirely:

visited = {("Delhi", "Red Fort"), ("Agra", "Taj Mahal")}
print(visited)

visited.add(["Jaipur", "Hawa Mahal"])

The first two lines work fine — a set of tuples is perfectly legal, since each tuple is locked and therefore trustworthy as a member. The third line raises TypeError: unhashable type: 'list'. This is not an arbitrary restriction; it is the direct, logical consequence of everything you learned in the first half of this chapter. Tuples earn their place inside sets (and, later, as dictionary keys) specifically because they are immutable. This is the single deepest reason the two topics of this chapter — sets and tuples — are taught together rather than as two unrelated chapters.

Choosing the Right Container

With lists, tuples, and sets all available, the choice comes down to three questions: does order matter, will the collection ever need editing after creation, and must every value be unique?

  • Use a list when order matters and you expect to add, remove, or edit items — a running scoreboard, a queue of print jobs, marks entered one at a time during an exam.
  • Use a tuple when order matters but the values, once decided, should never change — a date of birth (day, month, year), GPS coordinates (latitude, longitude), a single database record like the IRCTC ticket, or any function that needs to return more than one related value at once.
  • Use a set when order does not matter but uniqueness must be guaranteed and membership needs to be checked quickly — distinct roll numbers who attended, unique words in a paragraph, the set of subjects a student is registered for, or removing duplicates from a messy list in one line.

That last use is common enough to be worth its own worked example, because it is a favourite CBSE output-prediction question:

marks = [78, 85, 78, 90, 85, 78]
unique_marks = set(marks)
print(len(unique_marks))

Trace it: the list has six entries, but only three distinct values appear — 78, 85, and 90. Converting to a set collapses the repeats, so len(unique_marks) prints 3. Note also that unique_marks[0] would fail with TypeError: 'set' object is not subscriptable — a set has no positions to index into, since it has no order to index by.

Common Exam Traps, Collected

CBSE questions on this chapter tend to circle the same handful of ideas, so it's worth listing them together as a final checklist rather than meeting them scattered across a paper: identifying that (5) is an int while (5,) is a tuple; predicting that assigning to a tuple index raises TypeError; predicting that a set literal or a set() conversion silently drops duplicate values and changes len() accordingly; recognizing that {} is a dictionary, not an empty set; matching the four set-operator symbols (|, &, -, ^) to union, intersection, difference, and symmetric difference; and explaining, in words, why a list cannot be placed inside a set while a tuple can.

Test Yourself

  • What does type((7)) print, and what would you change to make it a one-element tuple?
  • Given colors = {"red", "green", "blue", "red"}, what does len(colors) print, and why?
  • Given a = {1, 2, 3, 4} and b = {3, 4, 5, 6}, work out a & b, a | b, a - b, and a ^ b by hand before checking in Python.
  • Why does coords = (12.9, 77.6) make more sense as a tuple than as a list, if it represents a fixed location's latitude and longitude?
  • Predict the exact error message produced by {[1, 2]}, and explain in one sentence why it happens.

Summary

  • A tuple is an ordered, indexable sequence, written with commas (parentheses are optional except for disambiguation), that cannot be changed after creation — attempting item assignment always raises TypeError.
  • A single-element tuple needs a trailing comma, as in (5,); without it, (5) is just an integer.
  • Tuple unpacking assigns each position of a tuple to a separate variable in one line, and the count of variables must match the tuple's length exactly.
  • A set is an unordered collection that automatically eliminates duplicates and supports very fast membership testing with in.
  • Sets never guarantee any particular display order — appearing sorted for small integers is a coincidence of hashing, not a language guarantee — and {} always means an empty dictionary, never an empty set.
  • The four core set operations — union (|), intersection (&), difference (-), and symmetric difference (^) — let you compare two groups directly instead of writing manual loops.
  • Only immutable, hashable values — numbers, strings, and tuples — can live inside a set or serve as a dictionary key; lists cannot, because their ability to change would break the set's internal structure. This is the reason tuples and sets belong in the same chapter: immutability is what earns a tuple its seat inside a set.

Practice Exercises

Now it is time to practice! Complete these challenges to solidify your understanding:

  • Exercise 1: Write a short program that demonstrates the core concept from this chapter. Test it with at least 3 different inputs.
  • Exercise 2: Find a real-world example where sets and tuples: immutable and unique collections is used in an Indian company (like TCS, Infosys, Flipkart, or ISRO). Write a paragraph explaining the connection.
  • Exercise 3: Create a mind-map connecting sets and tuples: immutable and unique collections to at least 3 other topics you have studied.
← Advanced Python Lists: Beyond the BasicsError Handling: Making Robust Python Programs →

Found this useful? Share it!

📱 WhatsApp 🐦 Twitter 💼 LinkedIn