Khi làm việc với Python, chắc hẳn bạn và mình đều thường xuyên gặp dictionary
(hay dict
). Đây là cấu trúc dữ liệu quen thuộc nhờ khả năng lưu trữ và truy xuất nhanh theo cặp key–value. Tuy vậy, để khai thác tối đa sức mạnh của nó, chúng ta cần nắm vững những hàm và phương thức xử lý đi kèm.
Trong bài viết này, thay vì chỉ liệt kê khô khan, mình muốn cùng bạn “đi một vòng” qua các thao tác quan trọng nhất với dict
: từ khởi tạo, truy xuất, thêm/xóa, cho đến các thủ thuật nâng cao và tối ưu hiệu suất. Mỗi phần sẽ có ví dụ minh họa kèm giải thích chi tiết, để cả hai chúng ta vừa ôn lại kiến thức, vừa củng cố thêm kinh nghiệm sử dụng dict
trong thực tế.
Bảng tổng hợp các thao tác phổ biến với Dictionary trong Python
Nhóm thao tác | Phương thức / Cách dùng | Mô tả |
---|---|---|
Khởi tạo | dict() , {} , dict.fromkeys(keys, value) | Tạo dictionary rỗng hoặc với giá trị mặc định |
Truy xuất | dict[key] , dict.get(key, default) | Lấy value theo key, có thể kèm giá trị mặc định |
Kiểm tra | key in dict | Kiểm tra key có tồn tại trong dictionary hay không |
Thêm/Cập nhật | dict[key] = value , dict.update(other) | Thêm key mới hoặc cập nhật value |
Xóa | dict.pop(key, default) , del dict[key] , dict.popitem() , dict.clear() | Xóa phần tử theo key, xóa phần tử cuối cùng, hoặc xóa toàn bộ dictionary |
Truy xuất tập hợp | dict.keys() , dict.values() , dict.items() | Trả về view chứa keys, values hoặc items |
Sao chép | dict.copy() , copy.deepcopy(dict) | Tạo bản sao shallow hoặc deep |
Khởi tạo có điều kiện | dict.setdefault(key, default) | Lấy value nếu key tồn tại, nếu không thì gán giá trị mặc định |
Comprehension | {k: v for k, v in iterable} | Tạo dictionary bằng biểu thức duyệt (ngắn gọn, linh hoạt) |
Hợp nhất | `dict1 | dict2(Python 3.9+), {**d1, **d2}` |
1. Khởi tạo Dictionary
Python cung cấp nhiều cách khởi tạo dict
. Hiểu rõ cách tạo giúp code ngắn gọn và tránh lỗi.
# Create empty dictionaries
empty1 = {} # literal syntax
empty2 = dict() # dict constructor
# Create with initial key-value pairs
person = {"name": "Alice", "age": 30}
# Create from iterable of pairs
pairs = [("id", 1), ("score", 95)]
from_pairs = dict(pairs)
# Create using fromkeys (all values the same)
keys = ["a", "b", "c"]
default_map = dict.fromkeys(keys, 0)
Giải thích chi tiết:
{}
là cách nhanh và phổ biến nhất để tạo dictionary rỗng.dict()
hữu dụng khi bạn xây dựng dict từ iterable (ví dụdict(list_of_pairs)
).fromkeys()
tạo cùng một đối tượng value cho mọi key — cẩn thận nếu value là mutable (tham chiếu chung).
2. Truy xuất và tìm kiếm phần tử
Truy xuất theo key là thao tác cơ bản; cần phân biệt giữa truy xuất trực tiếp và truy xuất an toàn.
student = {"name": "Bob", "gpa": 3.6}
# Direct indexing (may raise KeyError)
try:
major = student["major"]
except KeyError:
print("Key 'major' not found")
# Safe access with get()
major_safe = student.get("major", "Undeclared")
# Check existence
has_name = "name" in student
Giải thích chi tiết:
student["major"]
sẽ raiseKeyError
nếu key không tồn tại — dùngtry/except
nếu bạn muốn xử lý ngoại lệ.student.get("major", "Undeclared")
trả về giá trị mặc định nếu key không tồn tại — đây là pattern an toàn và thường được dùng.key in dict
trả vềTrue/False
rất nhanh (O(1) trung bình) vì dict dùng hash table.
3. Thêm và cập nhật phần tử
Thêm hoặc cập nhật là thao tác đơn giản nhưng có vài lưu ý khi update nhiều phần tử.
config = {"host": "localhost", "port": 8000}
# Add or update single key
config["debug"] = True
config["port"] = 8080 # overwrite existing value
# Update from another dict
more = {"timeout": 30, "port": 9000}
config.update(more) # config["port"] becomes 9000
Giải thích chi tiết:
- Gán
config[key] = value
thêm key mới hoặc ghi đè value nếu key tồn tại. update()
hợp nhất key/value từ dict khác; nếu có key trùng, giá trị của dict truyền vào sẽ ghi đè.
4. Xóa phần tử trong Dictionary
Có nhiều cách xóa, mỗi cách có hành vi và return khác nhau.
data = {"a": 1, "b": 2, "c": 3}
# pop: returns the removed value, can provide default
val = data.pop("b", None) # val == 2
# del: may raise KeyError if key not found
del data["c"]
# popitem: removes and returns an arbitrary/last item (Python 3.7+ guarantees LIFO)
k, v = data.popitem()
# clear: removes all items
data.clear()
Giải thích chi tiết:
pop(key, default)
an toàn hơnpop(key)
vì không raise lỗi nếu key không tồn tại (trả về default).del
trực tiếp xóa và sẽ raiseKeyError
nếu key không tồn tại — dùng khi bạn chắc chắn key tồn tại.popitem()
hữu dụng khi bạn cần lấy phần tử cuối cùng hoặc xử lý dict như stack.
5. Các phương thức làm việc với Key và Value
keys()
, values()
, items()
trả về view object (không phải list), có tính “live” — nghĩa là cập nhật khi dict thay đổi.
sample = {"x": 10, "y": 20}
k_view = sample.keys()
v_view = sample.values()
i_view = sample.items()
# Convert to list snapshot
keys_list = list(k_view)
Giải thích chi tiết:
- Views phản ánh thay đổi của dict: nếu bạn thêm key mới,
k_view
thay đổi theo. - Nếu cần một snapshot cố định để lặp an toàn sau đó, chuyển về
list()
.
6. Duyệt Dictionary
Duyệt dict
phổ biến trong xử lý dữ liệu — cần lưu ý khi sửa dict trong lúc iterate.
info = {"a": 1, "b": 2, "c": 3}
# Iterate over keys
for key in info:
print(key, info[key])
# Iterate over items (key, value)
for key, value in info.items():
print(key, value)
# Safe removal while iterating: iterate over list of keys
for key in list(info.keys()):
if info[key] % 2 == 1:
del info[key]
Giải thích chi tiết:
- Không nên thay đổi kích thước dict khi đang iterate trực tiếp — điều này gây
RuntimeError
hoặc hành vi không mong muốn. - Giải pháp: iterate trên
list(dict.keys())
để có snapshot và thay đổi dict an toàn.
7. Các phương thức hữu ích khác
Một số phương thức rất hữu dụng: copy()
, fromkeys()
, setdefault()
, và dict comprehension
. Cần hiểu shallow copy vs deep copy.
import copy
original = {"user": {"name": "Tom"}}
shallow = original.copy()
deep_copy = copy.deepcopy(original)
# setdefault: get value or set default if missing
val = original.setdefault("age", 25)
# dict comprehension
squared = {k: v * v for k, v in {1:1, 2:2, 3:3}.items()}
Giải thích chi tiết:
copy()
tạo shallow copy: nếu value là mutable object (ví dụ nested dict, list), both dicts chia sẻ cùng đối tượng con.copy.deepcopy()
tạo bản sao hoàn toàn, tránh side-effect khi thay đổi nested objects.setdefault(key, default)
trả về value nếu key tồn tại; nếu không có key thì thêm key với default và trả về default — hữu ích khi khởi tạo list trong group-by pattern.
8. Các thao tác nâng cao với Dictionary
Xử lý nested dict, merge dicts và sử dụng các pattern nâng cao.
# Merging dictionaries (Python 3.9+)
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
merged = a | b # {'x':1, 'y':20, 'z':3} -> b overwrites a
# Alternative (older Python)
merged2 = {**a, **b}
# Access nested dict safely
config = {"db": {"host": "localhost", "port": 5432}}
host = config.get("db", {}).get("host")
Giải thích chi tiết:
- Toán tử
|
(Python 3.9+) hợp nhất hai dict; khi có key trùng, value bên phải ghi đè. {**a, **b}
tương tự, dùng khi không có|
.- Với nested dict thường dùng
get(..., {})
để tránhAttributeError
.
9. Tối ưu hiệu suất khi làm việc với Dictionary
Hiểu độ phức tạp giúp chọn cấu trúc phù hợp.
- Key lookup: O(1) average.
- Value lookup / filter: O(n) vì phải duyệt toàn bộ values/items.
- Khi cần tìm theo value thường xuyên: xây dựng inverted index (map value → list of keys).
Ví dụ xây index:
from collections import defaultdict
users = {
"u1": {"name": "Alice", "city": "Hanoi"},
"u2": {"name": "Bob", "city": "Hanoi"},
"u3": {"name": "Carol", "city": "Hue"},
}
city_index = defaultdict(list)
for uid, info in users.items():
city_index[info.get("city")].append(uid)
# Lookup users in Hanoi quickly
hanoi_users = city_index["Hanoi"]
Giải thích chi tiết:
- Index giúp chuyển tốn thời gian O(n) thành O(1) cho tra cứu nhiều lần, đổi lại tốn thêm memory và cần cập nhật index khi data thay đổi.
10. Kết luận (phiên bản mới)
Sau khi cùng nhau đi qua từng phần, từ những thao tác cơ bản như khởi tạo, truy xuất, thêm và xóa phần tử, cho đến những kỹ thuật nâng cao như merge dict, dùng setdefault
, hay tối ưu hiệu suất bằng inverted index, chắc hẳn bạn cũng thấy rằng dictionary
thực sự là một công cụ mạnh mẽ trong Python.
Điều quan trọng không chỉ là “biết có hàm nào”, mà còn là hiểu được khi nào nên dùng cách nào để code vừa rõ ràng, vừa hiệu quả. Với mình, việc nắm vững các phương thức của dict
giúp tiết kiệm rất nhiều thời gian, đồng thời làm cho chương trình dễ bảo trì hơn trong tương lai.
Hy vọng bài viết này mang lại cho bạn những gợi ý hữu ích và cảm giác tự tin hơn mỗi khi xử lý dict
trong công việc hoặc học tập. Và biết đâu, trong quá trình áp dụng, bạn sẽ tự tìm ra thêm nhiều mẹo hay để chia sẻ ngược lại với cộng đồng.
11. Tài liệu tham khảo (APA)
- Python Software Foundation. (2024). Built-in Types — dict. Python Documentation. Retrieved from https://docs.python.org/3/library/stdtypes.html#dict
- Beazley, D., & Jones, B. K. (2013). Python Cookbook (3rd ed.). O’Reilly Media.
- Ramalho, L. (2015). Fluent Python: Clear, Concise, and Effective Programming. O’Reilly Media.