Chào mừng các bạn đến với Bài Giảng 4! Hôm nay chúng ta sẽ học về cấu trúc dữ liệu cuối cùng trong bộ tứ cơ bản: **Set (Tập hợp)**. Sau đó, chúng ta sẽ làm một bài tổng kết lớn để biết khi nào nên dùng List, Tuple, Dictionary hay Set nhé!
🎯 Mục Tiêu Bài Giảng
Kiến thức
Hiểu Set là gì: không có thứ tự và không trùng lặp.
Biết các phép toán cơ bản (hợp, giao).
Kỹ năng
Sử dụng Set để khử trùng lặp (loại bỏ phần tử giống nhau) khỏi List.
Phân biệt khi nào nên dùng List, Tuple, Dictionary, và Set.
⏱️ Phân Bổ Thời Gian (120 phút)
Set (Tập hợp) là một cấu trúc dữ liệu rất đặc biệt. Nó giống như một cái túi, chỉ quan tâm bạn có "món đồ" đó hay không, chứ không quan tâm nó nằm ở đâu hay có bao nhiêu cái.
1. Khái niệm Set (Tập hợp)
Set có 2 đặc điểm quan trọng:
Không có thứ tự (Unordered):
Các phần tử không được lưu theo index. Vì vậy, chúng ta không thể truy xuất bằng index (ví dụ: `my_set[0]` sẽ báo lỗi).
Không trùng lặp (Unique):
Mỗi phần tử chỉ xuất hiện 1 lần duy nhất. Nếu bạn cố thêm một phần tử đã có, Set sẽ tự động bỏ qua.
Tạo Set: Dùng dấu ngoặc nhọn `{}` nhưng không có cặp Key:Value.
my_set = {1, 2, 3, "a"}
print(my_set) # Kết quả có thể là {1, 2, 3, 'a'} (thứ tự có thể khác)
2. Tạo Set và Khử trùng lặp
🔥 Lưu ý khi tạo Set rỗng:
Nếu dùng `my_set = {}`, Python sẽ tạo ra một Dictionary rỗng. Để tạo Set rỗng, ta phải dùng hàm `set()`.
empty_dict = {} # Đây là Dictionary rỗng
empty_set = set() # Đây là Set rỗng
Ứng dụng quan trọng nhất: Khử trùng lặp
Đây là cách nhanh nhất để loại bỏ các phần tử trùng lặp khỏi một List.
# 1. Set tự động loại bỏ trùng lặp khi tạo
numbers = {1, 2, 2, 3, 3, 3}
print(numbers) # Kết quả: {1, 2, 3}
# 2. Chuyển đổi từ List -> Set để khử trùng lặp
my_list = [1, 2, "a", 2, "b", "a"]
unique_items = set(my_list)
print(unique_items) # Kết quả: {1, 2, 'b', 'a'} (thứ tự ngẫu nhiên)
3. Thêm và Xóa khỏi Set
my_set = {1, 2, 3}
# 1. Thêm 1 phần tử (nếu chưa có)
my_set.add(4)
print(my_set) # Kết quả: {1, 2, 3, 4}
# 2. Xóa (An toàn - discard): Xóa nếu có, không có cũng không lỗi
my_set.discard(2)
print(my_set) # Kết quả: {1, 3, 4}
my_set.discard(99) # Không có 99, không làm gì cả, không báo lỗi
# 3. Xóa (Báo lỗi - remove): Xóa, nếu không có sẽ báo lỗi KeyError
my_set.remove(1)
print(my_set) # Kết quả: {3, 4}
# my_set.remove(99) # Sẽ gây lỗi KeyError vì 99 không tồn tại
Vì Set là tập hợp (giống trong Toán học), chúng ta có thể thực hiện các phép toán Hợp (Union) và Giao (Intersection) rất dễ dàng.
1. Hợp (Union) và Giao (Intersection)
Kịch bản: 2 nhóm bạn A và B đăng ký đi dã ngoại.
A = {"An", "Bình", "Chi"}
B = {"Bình", "Dũng", "Em"}
1. Phép Hợp (Union |): Lấy tất cả (không lặp)
Dùng toán tử `|` hoặc phương thức `.union()`.
# Cách 1: Dùng toán tử |
tat_ca = A | B
print(tat_ca) # Kết quả: {'An', 'Bình', 'Chi', 'Dũng', 'Em'}
# Cách 2: Dùng phương thức .union()
tat_ca_2 = A.union(B)
print(tat_ca_2)
2. Phép Giao (Intersection &): Lấy phần chung
Dùng toán tử `&` hoặc phương thức `.intersection()`.
# Cách 1: Dùng toán tử &
di_ca_2_nhom = A & B
print(di_ca_2_nhom) # Kết quả: {'Bình'}
# Cách 2: Dùng phương thức .intersection()
di_ca_2_nhom_2 = A.intersection(B)
print(di_ca_2_nhom_2)
Bài tập Thực hành: Phép Toán Set
Cho 2 List điểm số của 2 bài kiểm tra:
diem_lan_1 = [5, 6, 7, 8, 8, 5]
diem_lan_2 = [7, 8, 9, 9, 10, 6]
Tìm tất cả các điểm số khác nhau đã xuất hiện trong cả 2 lần (dùng Set Hợp).
Tìm các điểm số cùng xuất hiện ở cả hai List (dùng Set Giao).
# Chuyển List sang Set để khử trùng lặp và tính toán
set_1 = set(diem_lan_1) # {5, 6, 7, 8}
set_2 = set(diem_lan_2) # {6, 7, 8, 9, 10}
# 1. Hợp (Tất cả điểm số)
tat_ca_diem = set_1 | set_2
print(f"Tất cả điểm đã xuất hiện: {tat_ca_diem}")
# 2. Giao (Điểm số chung)
diem_chung = set_1 & set_2
print(f"Các điểm xuất hiện ở cả 2 lần: {diem_chung}")
Đây là phần quan trọng nhất! Chúng ta đã học 4 cấu trúc dữ liệu: List, Tuple, Dictionary, Set. Vậy khi nào nên dùng cái nào?
1. Bảng So Sánh 4 Cấu Trúc Dữ Liệu
Cấu Trúc
Ký Hiệu
Có Thứ Tự? (Dùng Index)
Thay Đổi Được? (Mutable)
Cho Phép Trùng Lặp?
Khi Nào Dùng?
List
`[]`
✓ Có
✓ Có
✓ Có
Danh sách chung (cần thêm/xóa/sửa).
Tuple
`()`
✓ Có
✗ Không
✓ Có
Dữ liệu cố định, không đổi (tọa độ, hằng số).
Dictionary
`{Key:Value}`
✗ Không
✓ Có
✗ Không (Key)
Tra cứu dữ liệu (dùng tên/nhãn để tìm).
Set
`{Value}`
✗ Không
✓ Có
✗ Không
Khử trùng lặp, kiểm tra sự tồn tại, toán tập hợp.
2. Bài tập Tình huống: Chọn Cấu Trúc Phù Hợp
Hãy chọn cấu trúc dữ liệu (List, Tuple, Dictionary, Set) phù hợp nhất cho các kịch bản sau:
Lưu danh sách lớp (cần thêm/xóa học sinh)?
Lưu các tọa độ (X, Y, Z) của một điểm (cố định, không thay đổi)?
Lưu số điện thoại của bạn bè (dùng tên để tra SĐT)?
Lưu danh sách các môn học mà không muốn bị lặp lại?
List (Vì cần thay đổi (thêm/xóa) và có thứ tự).
Tuple (Vì dữ liệu cố định (bất biến) và có thứ tự).
Dictionary (Vì cần tra cứu (SĐT) bằng một "nhãn" (Tên)).