Wiki
Intro12 min read

Collections: lists, tuples, sets and dicts

The four built-in containers and the one question that picks between them: what does this data need to be cheap at?

You can represent almost anything with four containers, and choosing well is most of what separates fast code from slow code. The decision is rarely about what the data is and almost always about which operations must be cheap: order, membership, uniqueness, or lookup by key.

Ask what has to be fast

A list is a row of slots: fast to index, slow to search. A tuple is a frozen row. A set is a bag of unique items with near-instant membership. A dict maps keys to values with near-instant lookup. Pick by the operation you will run most, not by what the data looks like.

The explorer below stores the same additions in each container. Add duplicates and watch ordering, uniqueness and lookup cost diverge.

Add the same values to each container and watch ordering, duplicates and lookup change

lookup O(n)
add

list: ordered, duplicates allowed, 0-indexed

[] empty
False≈ 1 step to decide

A list answers membership by checking one element at a time; a set or dict jumps straight to a bucket. The cost is hidden in the container choice, which is why "is this value present?" is cheap on a set and expensive on a list even when both hold the same items.

The four containers

  • A list [1, 2, 3] is ordered and mutable. append is amortised O(1)O(1); membership and search are O(n)O(n) because they scan.
  • A tuple (1, 2, 3) is ordered and immutable. That immutability makes tuples usable as dictionary keys and signals "this record does not change".
  • A set {1, 2, 3} is unordered and holds each element once. Membership is O(1)O(1) on average because it hashes into buckets rather than scanning.
  • A dict {"a": 1, "b": 2} maps unique keys to values, also with O(1)O(1) average lookup. Since Python 3.7 it preserves insertion order, but that is a bonus, not the reason to use it.

Building the table

Membership is where the difference bites. x in my_list walks the list one element at a time — O(n)O(n). x in my_set hashes x, jumps to one bucket, and answers in O(1)O(1) on average. Converting a list to a set before a loop of membership tests is one of the most common rewrites for speed:

seen = set()
for word in document:
    if word in seen:      # O(1), not O(n)
        continue
    seen.add(word)

Sharing, copying and mutation

Assignment never copies a container; it binds another name to the same object.

a = [1, 2, 3]
b = a              # same object
b.append(4)        # a is now [1, 2, 3, 4] too
c = a[:]           # a shallow copy; c is independent

Because lists and dicts are mutable, passing one into a function lets that function change your data. Tuples and strings are immutable, so they cannot be changed in place — which is exactly why they are safer to share.

Union and intersection are set operations, not list operations

a | b and a & b combine and intersect sets. On lists the same symbols mean something else entirely (| is a TypeError for lists). When the question is "which items appear in both?", convert to sets first.

Illustrative vs real

The explorer uses single-character items and a handful of operations so the panel stays readable. Real containers hold arbitrary objects, nest inside one another, and are built with comprehensions such as [x * 2 for x in row]. The cost model — indexed O(1)O(1), scanned O(n)O(n), hashed O(1)O(1) average — is the same at any size, and only becomes visible at scale.

Check yourself

Eduspheria wiki · Programming & Data Structures, Python foundations

0 / 5 answered

  1. 1Which container gives average O(1) membership testing?
    Multiple choice
  2. 2Assigning a list to a second name copies it.
    True / false
  3. 3Which container type is immutable and therefore usable as a dictionary key?
    Short answer
  4. 4What does `[1, 2] + [3]` produce?
    Multiple choice
  5. 5How many distinct elements does the set `set([1, 1, 2, 3, 3])` contain?
    Numeric answer

From the exam paper

Modeled on NITJ AI-503, End-Sem December 2024

0 / 5 answered

  1. 1For the list ['p', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'i', 'n', 'g'], what does the slice list[2:5] evaluate to?
    Multiple choice
  2. 2For that same 11-element list, what is list[:-5]?
    Multiple choice
  3. 3For that same list, what is list[5:]?
    Multiple choice
  4. 4Writing list[:] produces a new list holding the same elements in the same order.
    True / false
  5. 5A program pairs up adjacent elements and swaps each pair, so element 0 moves to slot 1, element 1 to slot 0, and so on. Applied to [0, 1, 2, 3, 4, 5], what is the result?
    Multiple choice

Where next: functions — naming a block of work, giving it inputs, and keeping its variables local.