Set là cấu trúc dữ liệu rất hữu ích khi mình cần lưu tập hợp các phần tử không trùng và không quan tâm đến thứ tự. Khi xử lý dữ liệu thực tế — loại bỏ phần tử trùng, kiểm tra membership nhanh, hay thao tác các phép toán tập hợp — set
thường là lựa chọn phù hợp.
Bài viết này sẽ đi qua tất cả các cách thêm phần tử vào set trong Python: từ phương thức cơ bản add()
cho đến update()
, phép toán hợp (union), toán tử gán mở rộng (|=
), thao tác với frozenset
(immutable), các lưu ý về kiểu dữ liệu (hashable vs unhashable), và những best-practice & hiệu năng cần biết
1. Tổng quan ngắn (vài điểm nền tảng)
Trước khi vào cách thêm phần tử, mình tóm tắt vài đặc điểm quan trọng của set
:
set
là một unordered collection và không cho phép phần tử trùng — nghĩa là nếu bạn thêm một phần tử đã tồn tại,set
sẽ bỏ qua (không lỗi, không duplicate). Python documentation- Phần tử trong
set
phải là hashable (các kiểu immutable nhưint
,str
,tuple
nếu các phần tử bên trong cũng hashable). Nếu bạn cố gắng thêm mộtlist
(mutable, unhashable) sẽ nhậnTypeError
. Python documentation
Hai điểm trên sẽ lặp lại trong các ví dụ bên dưới vì chúng quyết định cách thêm phần tử sẽ hoạt động thế nào.
2. Thêm một phần tử: set.add(elem)
Đây là cách phổ biến nhất khi mình muốn thêm một phần tử đơn lẻ.
Ví dụ:
# Add one element to a set
fruits = {"apple", "banana"}
fruits.add("orange") # Add 'orange' to the set
print(fruits) # e.g. {'banana', 'apple', 'orange'}
Ghi chú:
add()
thay đổi set tại chỗ (in-place) và trả vềNone
— giống các phương thức thay đổi bộ sưu tập khác trong Python. Codecademy+1- Nếu
elem
đã tồn tại,add()
không gây lỗi và set giữ nguyên (không tạo bản sao). - Nếu
elem
không hashable (ví dụlist
), bạn sẽ thấyTypeError
:
s = set()
s.add([1, 2, 3]) # TypeError: unhashable type: 'list'
Để thêm một list
như một phần tử, bạn phải chuyển nó thành tuple
(nếu ý nghĩa dữ liệu cho phép): s.add(tuple([1,2,3]))
.
3. Thêm nhiều phần tử: set.update(iterable, ...)
Khi mình có một iterable (list, tuple, set, string, dict, generator, …) muốn thêm nhiều phần tử cùng lúc, update()
là lựa chọn đúng.
Ví dụ:
# Update set from different iterables
numbers = {1, 2}
numbers.update([3, 4]) # add from list
numbers.update((5, 6)) # add from tuple
numbers.update("78") # add chars '7' and '8'
numbers.update({9: 'a'}) # adding dict adds keys (9)
print(numbers) # {1,2,3,4,5,6,'7','8',9}
Ghi chú:
update()
thêm tất cả các phần tử từ iterable vào set (không thêm iterable như một phần tử duy nhất)update()
thay đổi set tại chỗ và trả vềNone
.- Vì
update()
lấy từng phần tử trong iterable nên khi truyềndict
thì các key được thêm chứ không phải key-value pair.
4. Tạo set mới bằng union()
hoặc toán tử |
(non-mutating)
Nếu bạn muốn lấy set cũ giữ nguyên và nhận set mới có thêm phần tử, dùng union()
hoặc toán tử |
.
Ví dụ:
a = {1, 2, 3}
b = {3, 4}
c = a.union(b) # returns a new set; a unchanged
# alternatively:
d = a | {5}
print(a, c, d) # a: {1,2,3} c: {1,2,3,4} d: {1,2,3,5}
Ghi chú:
union()
không sửa set ban đầu — nó trả về tập hợp mới; ngược lạiupdate()
sửa set tại chỗ. Đây là khác biệt quan trọng khi bạn muốn giữ tham chiếu cũ.
5. Toán tử gán mở rộng |=
(mutating union)
Nếu bạn muốn hợp (union
) nhưng cập nhật trực tiếp vào set hiện tại, dùng |=
:
a = {1, 2}
a |= {3, 4} # same as a.update({3,4})
print(a) # {1,2,3,4}
Ghi chú:
a |= b
tương đương vớia.update(b)
— thay đổi đối tượng a ngay lập tức. Nếu có biếnc = a
trước khi|=
thìc
cũng thấy thay đổi — vì đó là cùng 1 đối tượng. Điều này khác vớia = a | b
(dòng sau sẽ tạo set mới và gán lại).
6. Những tình huống thường gặp / mẹo nhỏ khi thêm vào set
- Thêm từ string →
update("abc")
sẽ thêm'a'
,'b'
,'c'
(từng ký tự). Nếu bạn muốn thêm cả một chuỗi như một phần tử, dùngadd("abc")
. - Thêm keys của dict →
update({'k': v})
thêm'k'
. Nếu bạn muốn thêm key-value, bạn không thể — set chỉ lưu giá trị đơn. - Thêm nhiều iterable cùng lúc →
s.update(list1, tuple1, set2)
—update
có thể nhận nhiều iterables. - Tránh thêm unhashable → nếu cần lưu cấu trúc mutable (ví dụ list) theo dạng “một phần tử”, hãy chuyển sang
tuple
hoặc dùngfrozenset
/ convert nội dung phù hợp.
7. Thêm vào frozenset
(immutable) — cách làm
frozenset
là phiên bản immutable của set
. Bạn không thể gọi add()
hay update()
trên frozenset
. Thay vào đó, tạo frozenset
mới bằng phép toán hợp (union):
fs = frozenset([1, 2])
fs2 = fs.union({3}) # returns a new frozenset or set-like object
print(fs, fs2)
# or using constructor:
fs3 = frozenset(list(fs) + [4])
Ghi chú: frozenset
dùng khi bạn cần một tập bất biến (ví dụ dùng làm key trong dict hoặc phần tử của set khác).
8. Hiệu năng & best practices khi thêm phần tử
set
trong Python được cài đặt trên hash table, do đó thêm phần tử trung bình là O(1) (average-case constant time). Tuy nhiên trong trường hợp xấu (hash collision hoặc rehashing) độ phức tạp có thể tăng lên. Vì vậy trong hầu hết trường hợp bạn có thể coiadd()
/update()
rất nhanh. Stack Overflow+1- Nếu bạn cần thêm rất nhiều phần tử lặp đi lặp lại, việc thu thập tất cả phần tử vào một iterable (list/other set) rồi dùng một lần
update()
thường hiệu quả hơn là lặp nhiều lầnadd()
. - Nếu bạn phải giữ tham chiếu cũ (nhiều biến trỏ tới cùng set) và không muốn ảnh hưởng biến khác, sử dụng
union()
để tạo set mới thay vìupdate()
hoặc|=
sẽ an toàn hơn.
9. Kết luận
Thêm phần tử vào set
trong Python không chỉ có một cách — mình có thể:
- dùng
add()
để thêm một phần tử và thay đổi set tại chỗ; - dùng
update()
để thêm nhiều phần tử từ iterable(s); - dùng
union()
hoặc|
để tạo set mới (non-mutating); - dùng
|=
để hợp và cập nhật ngay (mutating); - với
frozenset
(immutable) ta phải tạo bản sao mới (ví dụ bằngunion
).
Hiểu rõ sự khác biệt mutating vs non-mutating (ví dụ update()
vs union()
), và hashable vs unhashable (cái nào có thể thêm được) sẽ giúp bạn chọn phương pháp phù hợp và tránh lỗi thường gặp. Trong đa số trường hợp, add()
và update()
là đủ cho thao tác thêm — còn nếu bạn cần giữ set cũ thì dùng union()
10. Tài liệu tham khảo
- Python Software Foundation. Tutorial — Data structures: Sets. Python 3 Documentation. Python documentation
- Python Software Foundation. Reference — Data model (set and frozenset description). Python 3 Reference. Python documentation
- Codecademy. Python
set.add()
documentation (reference). Codecademy - GeeksforGeeks. Python Set
update()
. GeeksforGeeks - StackOverflow discussion — Difference between
union()
andupdate()
(mutating vs non-mutating).