Skip to content

Python · Data Structures

Python list vs tuple vs set — Choosing the Right Data Structure

6 min read Updated 2026-06-21 Share:

Practice List vs Tuple vs Set interview questions

Three containers, three different contracts

Python gives you three built-in containers that beginners often use interchangeably: list, tuple, and set. They look superficially similar — you can loop over all three — but they make fundamentally different promises about mutability, ordering, and lookup speed. Picking the wrong one leads to subtle bugs, slow code, and instant red flags in interviews. This guide untangles each contract and gives you a decision rule that makes the right choice obvious.

Quick-reference comparison

Propertylisttupleset
Mutable?YesNoYes (elements must be immutable)
Ordered?YesYesNo
Allows duplicates?YesYesNo — silently deduplicates
Indexable?Yes (a[0])Yes (t[0])No
Membership testO(n)O(n)O(1) average
Hashable?NoYes (if all elements are)No
Can be dict key?NoYesNo
Typical useGrowing collectionFixed recordMembership / dedup
Literal syntax[1, 2, 3](1, 2, 3) or 1, 2, 3{1, 2, 3}

list — the mutable, ordered sequence

A list holds a dynamic sequence of references to any Python objects, in the order you add them. Use it when the collection needs to grow, shrink, or be reordered.

scores = [90, 85, 70]
scores.append(60)        # mutate freely
scores.sort()            # [60, 70, 85, 90]
scores[0] = 55           # reassign any element

# lists allow duplicates and mixed types
items = [1, "hello", 1, None]  # valid

The most common interview trap: appending to the front (insert(0, x)) is O(n) because every element shifts right. Use collections.deque for fast front insertions.

Rule of thumb: reach for a list when you have a homogeneous, changing collection that you'll add to, sort, or filter — the default when you're unsure.

Deep dive: Lists & Slicing interview questions

tuple — the immutable record

A tuple is an immutable, fixed-length sequence. Its slots can't be reassigned after creation, which makes it the right structure for data that shouldn't change — coordinates, database rows, function return values, dictionary keys.

point = (3.0, 4.0)          # fixed record — a 2D coordinate
x, y = point                # tuple unpacking (clean, idiomatic)

# tuples as dict keys — works because they're hashable
distances = {(0, 0): 0, (3, 4): 5.0}

# immutability is shallow — a tuple of lists is mutable inside
t = ([1, 2], [3, 4])
t[0].append(99)             # allowed — mutates the list, not the tuple slot
t[0] = []                   # TypeError — can't reassign the slot itself

Because all elements must be hashable for the tuple to be hashable, (1, [2, 3]) raises TypeError on hash() — a classic gotcha.

Rule of thumb: reach for a tuple when the data is a fixed bundle that won't change — if you'd describe it as "a record" or "a point", it's a tuple.

Deep dive: Tuples & Named Tuples interview questions

set — the unordered, deduplicated membership checker

A set is a hash table of unique values with no defined order. Its superpower is O(1) average membership testing — regardless of how many elements are in the set, x in s costs the same.

seen = set()
seen.add(1)
seen.add(2)
seen.add(1)          # silently ignored — sets store unique elements only
print(seen)          # {1, 2}  (order not guaranteed)

# O(1) membership vs O(n) for lists
big_list = list(range(1_000_000))
big_set  = set(big_list)
999_999 in big_list  # scans up to 1 million elements
999_999 in big_set   # one hash lookup

# fast deduplication
names = ["alice", "bob", "alice", "carol"]
unique = list(set(names))   # ["alice", "bob", "carol"] — order lost

Sets also support the classic mathematical operations:

a = {1, 2, 3}
b = {2, 3, 4}
a | b   # {1, 2, 3, 4}  union
a & b   # {2, 3}        intersection
a - b   # {1}           difference
a ^ b   # {1, 4}        symmetric difference

Because sets use hashing internally, only hashable types can be elements — you can't have a set of lists. Use frozenset when you need an immutable, hashable set (e.g., as a dict key).

Rule of thumb: reach for a set when the question is "is X in this collection?" or "give me the unique items" — never when order or duplicates matter.

Deep dive: Sets & Frozensets interview questions

What about dict?

Dictionaries belong in this conversation too. A dict is essentially a set of unique keys, each mapped to a value. Since Python 3.7, insertion order is preserved. Use it when you need a key → value mapping, not just membership.

# prefer dict when you need to look up a value, not just check presence
cache = {}
cache["user_42"] = {"name": "Alice", "age": 30}
cache.get("user_99", None)   # safe lookup, no KeyError

Deep dive: Dictionaries interview questions

The decision rule

Answer three questions in order:

  1. Do I need key → value mapping?dict
  2. Will the collection change, or do I need ordering / indexing?
    • Yes, needs to change or be indexed → list
    • No, it's a fixed record → tuple
  3. Do I only need to know "is X a member?" or "what are the unique values?"set
# Q1: mapping needed? → dict
user = {"name": "Alice", "age": 30}

# Q2a: changing collection? → list
queue = ["task_a", "task_b"]
queue.append("task_c")

# Q2b: fixed record? → tuple
rgb = (255, 128, 0)           # color — never reassigns channels

# Q3: membership / unique? → set
visited_urls = set()
if url not in visited_urls:
    visited_urls.add(url)

Recap

A list is mutable, ordered, and allows duplicates — the default workhorse for growing collections. A tuple is immutable, ordered, hashable, and faster — use it for fixed records and dictionary keys. A set is unordered, deduplicated, and offers O(1) membership — reach for it whenever you need fast "is X in here?" or unique-values logic. When you need key-value pairs, add dict to the toolkit. The deciding factor is usually mutability first, then whether order or uniqueness matters more.

More ways to practice

The self-quiz is live. Get notified when mock interviews and new question packs drop.

or
Join our WhatsApp Channel