Python defaultdict: Xử Lý Dictionary Gọn Hơn, Sạch Hơn trong Python
- Home
- Python defaultdict: Xử Lý Dictionary Gọn Hơn, Sạch Hơn trong Python
Khi làm việc với Python, dictionary (dict) là một trong những kiểu dữ liệu được sử dụng phổ biến nhất. Tuy nhiên, bất kỳ ai làm việc với dict chuẩn đều từng gặp phải lỗi quen thuộc: KeyError.
Để tránh lỗi này, chúng ta thường phải dùng phương thức .get(), .setdefault() hoặc kiểm tra if key in dict thủ công. Điều này khiến mã nguồn trở nên dài dòng không cần thiết.
Trong bài viết này, hãy cùng DC SoftTech tìm hiểu defaultdict từ module tích hợp collections – giải pháp giúp bạn viết code xử lý dictionary ngắn gọn, tối ưu và chuyên nghiệp hơn.
Khi bạn truy cập hoặc cập nhật một key chưa tồn tại trong dict thường, Python sẽ ném ra ngoại lệ KeyError.
# Ví dụ: Đếm số lần xuất hiện của từng từ
words = ["python", "java", "python", "c++", "java", "python"]
word_count = {}
for word in words:
# Nếu không kiểm tra, dòng dưới sẽ báo lỗi KeyError ở lần xuất hiện đầu tiên của word
if word not in word_count:
word_count[word] = 0
word_count[word] += 1
Mặc dù có thể dùng word_count.setdefault(word, 0), cú pháp này vẫn chưa thực sự tự nhiên và dễ gây rối khi xử lý các cấu trúc dữ liệu phức tạp hơn (như danh sách hoặc danh sách lồng nhau).
defaultdict là một lớp con (subclass) của dict chuẩn, nằm trong module collections. Điểm đặc biệt của defaultdict là: nếu một key chưa tồn tại, nó sẽ tự động khởi tạo giá trị mặc định cho key đó dựa trên một hàm dựng (factory function) do bạn cung cấp.
from collections import defaultdict
# factory_function có thể là int, list, set, dict, hoặc một hàm custom
d = defaultdict(factory_function)
int) – Đếm phần tửKhi truyền int làm factory function, giá trị mặc định cho key mới sẽ là 0 (int() trả về 0).
from collections import defaultdict
words = ["python", "java", "python", "c++", "java", "python"]
word_count = defaultdict(int)
for word in words:
word_count[word] += 1 # Không cần kiểm tra key có tồn tại hay chưa!
print(dict(word_count))
# Output: {'python': 3, 'java': 2, 'c++': 1}
list) – Nhóm dữ liệuKhi truyền list, giá trị mặc định sẽ là một danh sách rỗng [] (list() trả về []). Rất thích hợp cho tác vụ gom nhóm (grouping).
from collections import defaultdict
# Gom nhóm sinh viên theo lớp
students = [
("Lớp A", "An"),
("Lớp B", "Bình"),
("Lớp A", "Cường"),
("Lớp B", "Dũng")
]
class_members = defaultdict(list)
for class_name, student_name in students:
class_members[class_name].append(student_name)
print(dict(class_members))
# Output: {'Lớp A': ['An', 'Cường'], 'Lớp B': ['Bình', 'Dũng']}
lambdaBạn có thể cung cấp bất kỳ hàm nào trả về giá trị mong muốn khi key chưa tồn tại.
from collections import defaultdict
# Mặc định mỗi item chưa có giá trị sẽ nhận chuỗi "N/A"
user_status = defaultdict(lambda: "N/A")
user_status["Alice"] = "Active"
print(user_status["Alice"]) # Output: Active
print(user_status["Bob"]) # Output: N/A (Key "Bob" tự động được tạo với giá trị "N/A")
| Tiêu chí | Dictionary Chuẩn (dict) | collections.defaultdict |
| Truy cập key chưa tồn tại | Báo lỗi KeyError |
Tự động tạo key với giá trị mặc định |
| Cú pháp khởi tạo | d = {} |
d = defaultdict(type) |
| Độ gọn gàng mã nguồn | Cần if/else hoặc .setdefault() |
Không cần kiểm tra sự tồn tại của key |
| Thư viện | Tích hợp sẵn trong ngôn ngữ | Cần from collections import defaultdict |
Tự động thêm key khi truy cập đọc (read access):
Chỉ cần bạn gọi d[key], ngay cả khi chỉ để kiểm tra hoặc in ra, defaultdict cũng sẽ tự động thêm key đó vào dictionary với giá trị mặc định.
d = defaultdict(int)
print(d["non_existent_key"]) # Output: 0
print(d) # Output: defaultdict(<class 'int'>, {'non_existent_key': 0})
Chuyển đổi về dict chuẩn khi cần:
Nếu cần trả về dữ liệu qua API hoặc ghi vào file JSON, bạn nên ép kiểu về dict thường bằng dict(d) để tránh các hành vi bất ngờ ở các module khác.
defaultdict là một công cụ nhỏ nhưng mang lại hiệu quả cực kỳ lớn trong việc làm sạch mã nguồn Python, loại bỏ các đoạn code kiểm tra điều kiện lặp đi lặp lại và tối ưu hiệu năng xử lý dữ liệu.
Hãy thử áp dụng defaultdict vào dự án tiếp theo của bạn để trải nghiệm sự khác biệt! Đừng quên theo dõi blog DC SoftTech để cập nhật thêm nhiều mẹo lập trình Python hữu ích khác.