All Posts
pythonPart 4 of python-basics-to-advanced

Python #4 — Lists, Tuples, Sets & Dictionaries

Python's four core collection types. When to use each, how to work with them efficiently, and comprehensions for all four.

R
by Rupa
Apr 7, 20255 min read

Lists — Ordered, Mutable Sequences

lists.py
Loading editor...

Sorting

numbers = [3, 1, 4, 1, 5, 9, 2, 6]

# sorted() — returns a new sorted list
asc  = sorted(numbers)                    # [1, 1, 2, 3, 4, 5, 6, 9]
desc = sorted(numbers, reverse=True)      # [9, 6, 5, 4, 3, 2, 1, 1]

# .sort() — sorts in place (modifies original)
numbers.sort()

# Sort by a key
people = [("Alice", 30), ("Bob", 25), ("Charlie", 35)]
by_age  = sorted(people, key=lambda p: p[1])
by_name = sorted(people, key=lambda p: p[0])

# Sort objects by attribute
from dataclasses import dataclass

@dataclass
class Student:
    name: str
    gpa: float

students = [Student("Alice", 3.8), Student("Bob", 3.5), Student("Charlie", 3.9)]
top = sorted(students, key=lambda s: s.gpa, reverse=True)
print(top[0].name)  # Charlie

Tuples — Ordered, Immutable

# Tuples can't be changed after creation
point = (3, 4)
rgb   = (255, 128, 0)
empty = ()
single = (42,)  # trailing comma required for single-element tuple

# Unpack
x, y = point
r, g, b = rgb
print(f"x={x}, y={y}")

# Swap without a temp variable
a, b = 1, 2
a, b = b, a
print(a, b)  # 2 1

# Named tuples — more readable
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)       # 3 4
print(p)              # Point(x=3, y=4)

# Extended unpacking
first, *rest = [1, 2, 3, 4, 5]
print(first)  # 1
print(rest)   # [2, 3, 4, 5]

head, *middle, last = [1, 2, 3, 4, 5]
print(head, middle, last)  # 1 [2, 3, 4] 5
When to use tuples vs lists

Use a tuple for heterogeneous data that won't change — coordinates, RGB values, a function returning multiple values. Use a list for a homogeneous collection you'll modify — a list of users, a queue of tasks.

Sets — Unordered, No Duplicates

# Sets are unordered and contain unique elements
tags = {"python", "backend", "api"}
tags.add("python")     # duplicate — silently ignored
tags.add("docker")
tags.discard("api")    # remove if exists (no error if missing)
print(tags)            # order is not guaranteed

# Set operations
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}

print(a | b)   # union:        {1, 2, 3, 4, 5, 6, 7, 8}
print(a & b)   # intersection: {4, 5}
print(a - b)   # difference:   {1, 2, 3}
print(a ^ b)   # symmetric difference: {1, 2, 3, 6, 7, 8}

# Membership test is O(1) — faster than list
big_set  = set(range(1_000_000))
big_list = list(range(1_000_000))

999_999 in big_set   # O(1) — fast
999_999 in big_list  # O(n) — slow

# Deduplicate a list while preserving order
from dict import fromkeys
nums = [1, 3, 2, 1, 4, 3, 5]
unique_ordered = list(dict.fromkeys(nums))
print(unique_ordered)  # [1, 3, 2, 4, 5]

Dictionaries — Key-Value Pairs

# Creating dicts
person = {"name": "Alice", "age": 30, "role": "admin"}
empty  = {}
from_keys = dict.fromkeys(["a", "b", "c"], 0)  # {"a": 0, "b": 0, "c": 0}

# Access
print(person["name"])              # Alice
print(person.get("email"))         # None (no KeyError)
print(person.get("email", "n/a"))  # n/a (default)

# Modify
person["email"] = "alice@dev.io"   # add
person["age"]   = 31               # update
person.update({"role": "superadmin", "active": True})

del person["role"]                 # delete key
popped = person.pop("active")      # remove and return value
person.setdefault("tags", [])      # set only if key doesn't exist

# Iterate
for key in person:                        # keys
    print(key)
for key, value in person.items():         # key-value pairs
    print(f"{key}: {value}")
keys   = list(person.keys())
values = list(person.values())

# Merge dicts (Python 3.9+)
defaults = {"color": "blue", "size": "M"}
overrides = {"size": "L", "weight": "light"}
merged = defaults | overrides              # {"color": "blue", "size": "L", "weight": "light"}

Dict Comprehension

# Square each number
squares = {n: n**2 for n in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Invert a dict (swap keys and values)
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
# {1: "a", 2: "b", 3: "c"}

# Filter a dict
scores = {"Alice": 95, "Bob": 72, "Charlie": 88, "Dave": 65}
passing = {name: score for name, score in scores.items() if score >= 80}
# {"Alice": 95, "Charlie": 88}

defaultdict and Counter

from collections import defaultdict, Counter

# defaultdict — auto-creates missing keys
word_lists = defaultdict(list)
for word in ["apple", "avocado", "banana", "blueberry", "cherry"]:
    word_lists[word[0]].append(word)

print(dict(word_lists))
# {"a": ["apple", "avocado"], "b": ["banana", "blueberry"], "c": ["cherry"]}

# Counter — count occurrences
words = ["python", "is", "great", "python", "is", "python"]
counts = Counter(words)
print(counts)              # Counter({'python': 3, 'is': 2, 'great': 1})
print(counts["python"])    # 3
print(counts.most_common(2))  # [('python', 3), ('is', 2)]

Choosing the Right Collection

NeedUse
Ordered, changeable sequencelist
Ordered, fixed data (coordinates, records)tuple
Unique items, fast membership testset
Key-value lookupdict
Count occurrencesCounter
Auto-initialise missing keysdefaultdict

What's Next?

Python #5 covers modules, packages, error handling with try/except, file I/O, and the standard library essentials — os, pathlib, json, datetime.

#python#basics#collections#lists#dicts

✦ Enjoyed this post?

Get posts like this in your inbox

No spam, just real tutorials when they're ready.

Discussion

Powered by GitHub

Comments use GitHub Discussions — no separate account needed if you have GitHub.