Menu

Set trong Python: phần tử duy nhất, hợp, giao và hiệu

Khi nào nên dùng set trong Python: phần tử không trùng lặp, kiểm tra in nhanh và các phép toán kiểu toán học (hợp, giao, hiệu) làm nên sức mạnh của set.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Set là một túi không thứ tự chứa các phần tử duy nhất

List và tuple quan tâm đến thứ tự, còn set thì không. List cho phép phần tử trùng chồng chất, còn set lặng lẽ bỏ chúng đi. Set, hay tập hợp, là cấu trúc dữ liệu phù hợp khi bạn có hai nhu cầu cụ thể:

  1. Bạn muốn các phần tử không trùng nhau, vậy thôi.
  2. Bạn muốn kiểm tra một phần tử có trong tập hay không thật nhanh.

Viết set bằng dấu ngoặc nhọn:

Các giá trị "red" và "green" bị trùng trong set thứ hai đơn giản là biến mất. Đó không phải lỗi, mà chính là mục đích của set.

Tạo set

Hai cách bạn sẽ thực sự dùng:

Điểm cuối cùng khiến ai cũng vấp ít nhất một lần: {} tạo ra một từ điển rỗng, không phải set rỗng. Cú pháp này buộc phải thuộc về một trong hai, và dict đã thắng.

Thêm và xóa phần tử

Khác biệt quan trọng là remove và discard: remove đòi phần tử phải có mặt; discard thì không quan tâm. Hãy chọn tùy theo việc thiếu phần tử đó có nên được coi là lỗi hay không.

Kiểm tra thành viên nhanh

Đây là lúc set thực sự chứng tỏ giá trị. x in some_set chạy trong thời gian hằng số, dù set lớn đến đâu. x in some_list phải duyệt qua cả list, nên sẽ chậm khi list lớn.

Quy tắc kinh nghiệm: bất cứ khi nào bạn thấy mình viết if x in some_list bên trong một vòng lặp và list có hơn vài chục phần tử, hãy chuyển list đó thành set trước.

Toán tập hợp

Đây là phần set trở nên thật sự thú vị. Bạn có thể kết hợp các set bằng những toán tử giống hệt các phép toán tập hợp trong toán học:

Mỗi toán tử cũng có dạng phương thức (.union(), .intersection(), .difference(), .symmetric_difference()). Toán tử thì gọn hơn; còn dạng phương thức nhận bất kỳ iterable nào, không chỉ một set khác.

Loại bỏ phần tử trùng trong list

Một trong những công dụng phổ biến nhất của set, kể cả ngoài "logic tập hợp":

Một dòng, hết trùng lặp. Có một điều cần lưu ý: thứ tự không được giữ nguyên. Nếu bạn cần vừa không trùng lặp vừa giữ thứ tự ban đầu, hãy dùng dict.fromkeys():

Trong Python hiện đại, dict giữ nguyên thứ tự chèn, và dict.fromkeys tạo một dict lấy các phần tử của iterable làm khóa, về bản chất là một set có thứ tự.

Tập con và tập cha

Kiểm tra xem một set có nằm trong set khác hay không:

Những phép kiểm tra này hay xuất hiện trong việc kiểm tra quyền ("người dùng này có đủ mọi vai trò cần thiết không?").

Những gì có thể nằm trong set

Chỉ những phần tử hashable. Đó là một thuật ngữ kỹ thuật, nhưng trên thực tế nó có nghĩa là:

  • Những thứ bất biến thì hashable: số, chuỗi, tuple chứa các phần tử hashable, frozenset.
  • Những thứ khả biến thì không: list, dict và các set khác không thể làm phần tử của set.

Nếu bạn cần một set chứa các set, hãy dùng frozenset, phiên bản bất biến của set.

Duyệt set không theo thứ tự

Lặp qua một set sẽ trả về các phần tử không theo thứ tự nào được đảm bảo:

Chạy đoạn đó vài lần, bạn sẽ thấy thứ tự thay đổi. Nếu thứ tự quan trọng, set không phải cấu trúc phù hợp: hãy sắp xếp nội dung khi cần dùng, hoặc dùng list.

Khi nào không nên dùng set

Nếu có bất kỳ điều nào sau đây đúng, list hoặc dict có lẽ sẽ hợp hơn:

  • Bạn quan tâm đến thứ tự.
  • Bạn cần lưu các phần tử trùng nhau.
  • Mỗi phần tử đi kèm dữ liệu liên quan (hãy dùng dict với phần tử đó làm khóa).

Đi tiếp

Set lo chuyện không trùng lặp và kiểm tra thành viên. Từ điển, sẽ học ở bài tiếp theo, xử lý mô hình rộng hơn là "tra một giá trị theo khóa", có lẽ là cấu trúc dữ liệu hữu ích nhất trong Python ngoài list.

Câu hỏi thường gặp

Set trong Python là gì?

Set là một tập hợp không có thứ tự gồm các phần tử không trùng nhau. Set dùng dấu ngoặc nhọn nhưng không có cặp khóa và giá trị: colors = {'red', 'green', 'blue'}. Thêm cùng một giá trị hai lần cũng không có tác dụng gì: phần tử trùng sẽ bị bỏ qua mà không báo lỗi.

Khi nào nên dùng set thay vì list?

Dùng set khi bạn cần các phần tử không trùng lặp hoặc khi phải kiểm tra phần tử có thuộc tập hay không nhiều lần (x in collection). Set tự động loại bỏ phần tử trùng và kiểm tra thành viên trong thời gian hằng số, với tập dữ liệu lớn thì nhanh hơn list rất nhiều.

Làm sao tạo một set rỗng trong Python?

Dùng set(), không phải {}: cặp ngoặc nhọn rỗng tạo ra một từ điển rỗng, không phải set rỗng. Khi đã có set, bạn có thể thêm phần tử bằng .add(value).

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu