datarekha

Lists, Tuples, Dicts, Sets & Gotchas

The four built-in collections and the gotchas GATE loves: append vs extend vs +, and aliasing vs copying a list.

8 min read Intermediate GATE DA Lesson 48 of 122

What you'll learn

  • Lists are mutable and ordered; tuples are immutable; dicts map keys to values; sets hold unique unordered items
  • append adds ONE element (even a whole list); extend adds each element; + builds a new list
  • Aliasing (b = a) shares one object; copying (b = a[:]) makes an independent list
  • Predicting list state after a real 2025 append/extend output question

Before you start

Last lesson closed on a sharp question: write b = a for a list a, and do you get a brand-new list, or merely a new name for the old one? Hold onto that question — its answer surprises people, and it is one of the two behaviours GATE leans on hardest in this whole topic.

Python gives you four built-in collections, and the exam’s favourite traps are both about what changed and what did not: the difference between append, extend, and +, and the difference between aliasing a list and copying it. Get those two right and most collection output questions simply fall open. Neither is an exam artefact, either — “I changed one list and another one mutated too” is among the most common real bugs in day-to-day data-wrangling code.

The four collections

list [1, 2, 3]mutable, ordered, indexablecan grow, shrink, reassign itemstuple (1, 2, 3)immutable, ordered, indexablefixed once created; hashabledict {‘a’: 1}key → value mappingkeys unique; lookup by keyset {1, 2, 3}unique, unorderedduplicates collapse; no indexing
Mutability and ordering are the two axes that decide each type’s behaviour.
  • List [1, 2, 3] — mutable, ordered, indexable. The workhorse.
  • Tuple (1, 2, 3) — like a list but immutable: you cannot change it after creation. Because it is fixed, it can serve as a dict key.
  • Dict `{'a': 1, 'b': 2}` — maps unique keys to values; you look items up by key. Assigning an existing key overwrites it (so len does not grow).
  • Set `{1, 2, 3}` — an unordered collection of unique items. Duplicates collapse, so `{1, 2, 2, 3}` has size 3.

append vs extend vs + — one element, or each element?

This is the single most-tested list distinction. Given a list A and another list B:

A = [1, 2, 3] B = [4, 5, 6]A.append(B)[1, 2, 3, [4,5,6]]B added as ONEnested elementlen = 4A.extend(B)[1, 2, 3, 4, 5, 6]EACH element ofB added in turnlen = 6A + B[1, 2, 3, 4, 5, 6]NEW list returned;A is unchangedA still len 3append and extend mutate A in place; + leaves A alone and hands back a new list.
Same two lists, three different results — the distinction GATE 2025 tested directly.
  • A.append(x) adds x as one element — even if x is itself a list, it goes in nested. Length grows by exactly 1.
  • A.extend(B) adds each element of B one by one. Length grows by len(B).
  • A + B builds and returns a new list; it does not change A (you must write A = A + B to keep the result).

append and extend mutate the list in place and return None; + returns a fresh list and leaves both operands alone. Seeing the three run side by side makes the distinction concrete:

A = [1, 2, 3]; B = [4, 5, 6]
A.append(B)
print("append:", A, "| len:", len(A))

A = [1, 2, 3]; B = [4, 5, 6]
A.extend(B)
print("extend:", A, "| len:", len(A))

A = [1, 2, 3]; B = [4, 5, 6]
C = A + B
print("plus  :", "A =", A, "| C =", C)

prints, exactly:

append: [1, 2, 3, [4, 5, 6]] | len: 4
extend: [1, 2, 3, 4, 5, 6] | len: 6
plus  : A = [1, 2, 3] | C = [1, 2, 3, 4, 5, 6]

append made a length-4 list with B buried inside it; only extend produced the flat six-item list; and + left A untouched while building C.

Aliasing vs copying

Now back to the question from last lesson. Assigning a list with = does not copy it — both names point at the same object, like two nicknames for one person. Mutating through one name is therefore visible through the other:

a = [1, 2, 3]
b = a          # ALIAS: b and a are the same list object
b.append(4)
print("a:", a)            # a changed too!

a = [1, 2, 3]
c = a[:]       # COPY: a[:] (or list(a)) builds a new, independent list
c.append(4)
print("a:", a, "| c:", c)

prints, exactly:

a: [1, 2, 3, 4]
a: [1, 2, 3] | c: [1, 2, 3, 4]

So b = a shares one list — appending through b changes a too. To get an independent copy, slice it (a[:]), rebuild it (list(a)), or call a.copy(). That is the answer to last lesson’s question: b = a gives you a second name, not a second list.

How GATE asks this

A pure predict-the-output MCQ: a snippet builds a list, calls append/extend or aliases it, and you pick the final value (or its length) from four options. The distractors are exactly the other operations’ results — so the question is really checking whether you know that append nests, extend flattens, + is non-mutating, and = aliases. This appeared in GATE DA 2025.

Worked example — a real 2025 question

Start with A = [1, 2, 3] and B = [4, 5, 6]. Which single operation makes A equal to [1, 2, 3, 4, 5, 6]?

Check each against what you just traced:

  • A.append(B)A becomes [1, 2, 3, [4, 5, 6]]. B is added as one element, producing a nested list of length 4. Not equal.
  • A.extend(B)A becomes [1, 2, 3, 4, 5, 6]. Each of 4, 5, 6 is appended in turn, length 6. This is the answer.
  • A + B → evaluates to [1, 2, 3, 4, 5, 6] but does not change A; A is still [1, 2, 3] afterward (unless you reassign with A = A + B).

So only A.extend(B) mutates A into [1, 2, 3, 4, 5, 6]. This is GATE DA 2025’s list-operation question — and the three distractors are precisely the other operations’ results.

A question to carry forward

That aliasing rule has a sting in its tail. It is not really about the = sign at all — it is about any two names reaching the same list. And the most common way a second name appears is when you pass a list into a function: the function’s parameter becomes another alias for the caller’s list, so a mutation inside the function leaks back out. That hints at a bigger topic. Here is the thread onward: when you call a function, what names can it actually see and change — and is there a notorious trap waiting when a function’s default argument is itself a mutable list that quietly survives from one call to the next?

In one breath

  • Four collections: list (mutable, ordered), tuple (immutable, hashable → dict key), dict (unique keys → values), set (unique, unordered — duplicates collapse).
  • append vs extend vs +: append(B) adds B as one nested element (len +1); extend(B) adds each element (len +len(B)); A + B returns a new list, A unchanged.
  • append/extend mutate in place and return None; + returns a fresh list.
  • Aliasing: b = a shares one object — mutating b changes a. Copy with a[:], list(a), or a.copy().
  • The alias rule fires for function arguments too: passing a list lets the function mutate the caller’s list.

Practice

Quick check

0/7
Q1Recall: which statements about Python collections are TRUE? (select all that apply)select all that apply
Q2Recall: s = {1, 2, 2, 3, 3, 3}. What is len(s)? (integer)numerical answer — type a number
Q3Trace: A = [1, 2, 3]; B = [4, 5, 6]; A.append(B). What is len(A) afterward? (integer)numerical answer — type a number
Q4Apply: a = [1, 2, 3]; b = a; b.append(4); print(a). What is printed?
Q5Apply: which operations leave the original list A = [1, 2, 3] UNCHANGED? (select all that apply)select all that apply
Q6Apply: A = [1, 2, 3]; B = [4, 5, 6]; C = A + B. What are A and C?
Q7Create: def tag(item, basket): basket.append(item); return basket. You run cart = ['milk']; tag('eggs', cart). What does cart hold afterward?

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions
How do list, dict, and set comprehensions work in Python, and when should you avoid them?

Comprehensions are syntactic sugar for building a new collection by iterating over an iterable and optionally filtering elements. They are faster than equivalent for-loops because the iteration runs at the C level inside the interpreter. Avoid them when the expression is too complex to read at a glance — a plain loop with descriptive variable names is preferable.

Given a new data problem, how do you decide whether to use a list, dict, or set?

Choose a list when order matters and you need indexed access or duplicates. Choose a dict when you need to map keys to values and look up by key in O(1). Choose a set when you need uniqueness, fast membership testing, or set-algebra operations. Getting this choice wrong usually means either incorrect results (keeping duplicates when you needed uniqueness) or avoidable O(n) lookups.

What is the difference between a list and a tuple, and when should you use each?

Lists are mutable sequences; tuples are immutable. Use a tuple when the collection of items is fixed by meaning — coordinates, RGB values, function return values — and a list when the collection will grow, shrink, or be modified in place. Immutability also makes tuples hashable, so they can serve as dict keys or set members.

What set operations does Python support, and where are they practically useful in data work?

Python sets support union, intersection, difference, and symmetric difference as both operators and methods, all running in O(min(m,n)) to O(m+n) time. They are useful for deduplication, membership testing in large collections, and computing overlaps between datasets — operations that would be expensive with lists.

Related lessons

Explore further

Skip to content