Previous | Tutorial index | Next
Sets and dictionaries are two essential non‑sequence data structures in Python. They are both unordered, mutable collections (with some caveats), but they serve very different purposes:
This tutorial dives deep into both, covering their creation, methods, operations, and best practices.
A set is an unordered, mutable collection of distinct, hashable objects. Because it is unordered, sets do not support indexing, slicing, or any sequence operations.
fruits = {"apple", "banana", "cherry"}
set() because {} creates an empty dictionary.empty_set = set()
set() constructor from any iterable:numbers = set([1, 2, 2, 3]) # {1, 2, 3} – duplicates removed
letters = set("hello") # {'h', 'e', 'l', 'o'} (order arbitrary)
frozenset for that.add(elem) – adds elem to the set (does nothing if already present).remove(elem) – removes elem; raises KeyError if not found.discard(elem) – removes elem if present; does nothing otherwise.pop() – removes and returns an arbitrary element (raises KeyError if empty).clear() – removes all elements.s = {1, 2, 3}
s.add(4) # {1, 2, 3, 4}
s.add(2) # {1, 2, 3, 4} (unchanged)
s.remove(3) # {1, 2, 4}
s.discard(5) # no effect
popped = s.pop() # removes an arbitrary element (say 1)
s.clear() # set()
Sets support all standard mathematical set operations. You can use both methods and operators:
| Operation | Method | Operator | Description |
|---|---|---|---|
| Union | set1.union(set2, ...) |
set1 | set2 |
All elements from both sets |
| Intersection | set1.intersection(set2, ...) |
set1 & set2 |
Common elements |
| Difference | set1.difference(set2, ...) |
set1 - set2 |
Elements in set1 but not in set2 |
| Symmetric Difference | set1.symmetric_difference(set2) |
set1 ^ set2 |
Elements in exactly one of the sets |
| Subset / Superset | set1.issubset(set2), set1.issuperset(set2) |
<=, >= |
Check inclusion |
| Disjoint | set1.isdisjoint(set2) |
– | No common elements |
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
print(A | B) # {1, 2, 3, 4, 5, 6}
print(A & B) # {3, 4}
print(A - B) # {1, 2}
print(A ^ B) # {1, 2, 5, 6}
print(A.issubset(B)) # False
In‑place updates: Methods like
update(),intersection_update(),difference_update(), andsymmetric_difference_update()modify the set in place.
Like lists, sets support comprehensions:
squares = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
even = {x for x in range(10) if x % 2 == 0} # {0, 2, 4, 6, 8}
frozenset – Immutable SetsA frozenset is an immutable version of a set. It is hashable, so it can be used as a dictionary key or as an element of another set.
fs = frozenset([1, 2, 3])
# fs.add(4) # AttributeError
A dictionary (dict) is an unordered, mutable collection of key‑value pairs. Each key must be hashable (immutable), and keys are unique within a dictionary.
person = {"name": "Alice", "age": 30, "city": "New York"}
empty_dict = {}
dict() constructor:# From a list of tuples
items = [("a", 1), ("b", 2)]
d = dict(items) # {'a': 1, 'b': 2}
# Using keyword arguments
d = dict(name="Bob", age=25) # {'name': 'Bob', 'age': 25}
dict.fromkeys(keys, value) – creates a dictionary with given keys and a default value (defaults to None).keys = ["x", "y", "z"]
d = dict.fromkeys(keys, 0) # {'x': 0, 'y': 0, 'z': 0}
d[key] (raises KeyError if missing) or d.get(key, default) (returns default if missing, default is None).d[key] = value (if key exists, updates; otherwise adds).del d[key] (raises KeyError if missing), pop(key) (removes and returns value), popitem() (removes and returns an arbitrary key‑value pair as a tuple, useful for LIFO operations), clear().d = {"a": 1, "b": 2}
print(d["a"]) # 1
print(d.get("c", 0)) # 0 (no KeyError)
d["c"] = 3 # add
d["a"] = 99 # update
del d["b"] # remove 'b'
value = d.pop("c") # returns 3, d is now {'a': 99}
Dictionaries are iterable; by default you iterate over keys.
d.keys() – a view of all keys.d.values() – a view of all values.d.items() – a view of all (key, value) pairs as tuples.Views are dynamic – they reflect changes to the dictionary.
for key in d:
print(key, d[key])
for key, value in d.items():
print(key, value)
# Convert to lists if needed
list(d.keys()) # ['a', ...]
update(other_dict) – merges other_dict into d (overwrites existing keys). Can take a dict, iterable of pairs, or keyword arguments.setdefault(key, default) – returns value if key exists; otherwise sets d[key] = default and returns default.copy() – shallow copy.d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
d1.update(d2) # d1 becomes {'a': 1, 'b': 3, 'c': 4}
d1.setdefault("d", 5) # adds key 'd' with value 5
Similar to list/set comprehensions:
squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
d3 = d1 | d2 – creates a new dictionary merging d1 and d2 (latter wins).d1 |= d2 – in‑place update.| Feature | Set | Dictionary | List | Tuple |
|---|---|---|---|---|
| Ordered? | No (since Python 3.7, dicts preserve insertion order; sets are still unordered) | Yes (insertion order preserved) | Yes | Yes |
| Mutable? | Yes | Yes | Yes | No |
| Indexable? | No | By key | By integer | By integer |
| Duplicate Elements? | No (unique elements) | No (unique keys; values can duplicate) | Yes | Yes |
| Hashable? | No (set itself) | No (dict itself) | No | Yes (if all elements hashable) |
| Use Cases | Unique collection, membership, set ops | Key‑value lookups, structured data | Sequence of items | Fixed sequence |
How do you create an empty set in Python?
{}set()[]()What is the output of {1, 2, 3} & {2, 3, 4}?
{1, 2, 3, 4}{2, 3}{1, 4}{2, 3, 4}True or False: Dictionaries are unordered, so you cannot rely on the order of keys when iterating.
Which method returns the value for a key if it exists, otherwise returns a default without raising an error?
pop()get()setdefault()items()What is the result of list({"a": 1, "b": 2}.keys())?
[1, 2]['a', 'b'][('a', 1), ('b', 2)]{'a', 'b'}Which of the following can be a dictionary key?
[1, 2](1, 2){1, 2}What does s = {1, 2, 3}; s.discard(2) do?
2 from s.KeyError because 2 is not in the set.2.What is the output of {x**2 for x in range(3)}?
{0, 1, 4}[0, 1, 4]{0:0, 1:1, 2:4}(0, 1, 4)How can you merge two dictionaries d1 and d2 (with d2 taking precedence) in Python 3.9+?
d1.update(d2){**d1, **d2}d1 | d2Which set operation returns elements that are in exactly one of the two sets?
Exercise 1: Set Operations
Given two sets:
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
Write code to:
Exercise 2: Remove Duplicates from a List
Write a function unique_elements(lst) that returns a new list with duplicates removed, preserving the order of first occurrence. Use a set to help, but note that sets are unordered; you need to preserve order. Hint: Use a loop and a set to track seen elements.
Exercise 3: Word Frequency with Dictionary
Given the string text = "the quick brown fox jumps over the lazy dog the quick fox", write a program that:
.split()).Exercise 4: Dictionary Manipulation
Create a dictionary inventory = {"apple": 10, "banana": 5, "orange": 8, "grape": 3}.
"pear": 6."apple" to 12."grape" from the dictionary.Exercise 5: Set Comprehensions
Use a set comprehension to create:
"Hello World".1. Course Enrollment System
You are given two lists: students = ["Alice", "Bob", "Charlie", "Diana", "Eve"] and courses = ["Math", "Physics", "Chemistry"].
Create a dictionary where each student maps to a set of courses they are enrolled in (start empty). Write functions to:
enroll(student, course) – add the course to the student's set.drop(student, course) – remove the course if present.get_courses(student) – return the set of courses for that student.get_students(course) – return a set of students enrolled in that course.common_courses(student1, student2) – return the intersection of their courses.all_courses() – return a set of all courses offered.def enroll(student, course): if student in enrollment: enrollment[student].add(course)
def drop(student, course): if student in enrollment: enrollment[student].discard(course)
def get_courses(student): return enrollment.get(student, set())
def get_students(course): return {s for s, cs in enrollment.items() if course in cs}
def common_courses(s1, s2): return get_courses(s1) & get_courses(s2)
def all_courses(): return set(courses)
</details>
**2. Inverted Dictionary**
Write a function `invert_dict(d)` that returns a new dictionary where the values become keys and the keys become values. If multiple keys have the same value, the inverted dictionary should map that value to a **set** of all original keys.
<details><summary>Sample Answer</summary>
```python
def invert_dict(d):
inverted = {}
for key, value in d.items():
inverted.setdefault(value, set()).add(key)
return inverted
3. Anagram Finder
Write a function anagram_groups(words) that groups anagrams together using a dictionary.
4. Set of Sets – Using Frozenset
Given a list of sets, write a function unique_sets(list_of_sets) that returns a list of unique sets (no duplicates). Use frozenset.
5. Character Frequency with Dictionary and Set
Write a program that reads a text file (or a multi‑line string) and computes:
get_students(course), iterate over all students' sets to see if course is in there.setdefault(value, set()).add(key).key = ''.join(sorted(word)); use defaultdict(list).frozenset(s) as a key in a set or dict, then extract.collections.Counter or manual dict. To get frequency descending: sorted(freq.items(), key=lambda kv: kv[1], reverse=True).In this tutorial, you have learned:
frozenset and merging dictionaries.Sets and dictionaries are indispensable tools for writing efficient and clean Python code. With this knowledge, you can now handle unique collections and key‑value data with ease.
Next Steps: In Tutorial 6, we will cover File I/O and Exception Handling – reading and writing files, and managing errors gracefully.
Happy coding with sets and dictionaries!