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.

1. Vấn Đề Với Dictionary Chuẩn Trong Python

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).

2. Python defaultdict Là Gì?

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.

Cú pháp cơ bản:

from collections import defaultdict

# factory_function có thể là int, list, set, dict, hoặc một hàm custom
d = defaultdict(factory_function)

3. Các Trường Hợp Sử Dụng Phổ Biến Của defaultdict

3.1. Giá trị mặc định là Số (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}

3.2. Giá trị mặc định là Danh sách (list) – Nhóm dữ liệu

Khi 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']}

3.3. Tự định nghĩa giá trị mặc định bằng lambda

Bạ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")

4. Bảng So Sánh: Dict Thường vs defaultdict

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

5. Lưu Ý Quan Trọng Khi Sử Dụng defaultdict

  1. 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})
    
  2. 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.

Lời Kết từ DC SoftTech

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.

Categories:

Leave Comment