Cấu trúc dữ liệu từ điển Dictionary trong Python

21095

Bài viết được sự cho phép của tác giả Kien Dang Chung

Trong Python có tới 4 kiểu cấu trúc dữ liệu là List, Tuple, Set và Dictionary. Trong các bài trước chúng ta đã lần lượt làm quen với các kiểu dữ liệu này và còn lại Dictionary, một cấu trúc rất hay dùng trong Python. Trong bài viết này, cùng TopDev tìm hiểu về cấu trúc dữ liệu từ điển Dictionary trong Python.

Từ điển – Dictionary trong Python

Từ điển dữ liệu (Dictionary) còn được gọi là mảng liên kết (associative array) trong một số ngôn ngữ lập trình, là một dạng danh sách như bạn đã được tìm hiểu. Có một điểm khác là các phần tử trong danh sách được truy xuất thông qua vị trí thì phần tử trong từ điển được truy xuất qua khóa (key). Bạn có thể định nghĩa khóa này, nó có thể là một chuỗi hoặc số nhưng nó phải là duy nhất trong từ điển.

Tại sao vậy? Chúng ta liên tưởng đến nhưng tình huống thực tế như, hai người có cùng một số điện thoại, vậy khi gọi đến biết ai là người nghe máy. Hai người có cùng một số tài khoản, vậy biết chuyển khoản cho ai bây giờ? Chính vì vậy, khóa (key) trong từ điển phải là duy nhất.

Vậy kiểu dữ liệu Dict trong Python là gì?

Kiểu dữ liệu Dict (viết tắt của Dictionary) trong Python là một kiểu dữ liệu lưu trữ các cặp key-value, tương tự như List và Tuple. Tuy nhiên, các giá trị trong Dict không được sắp xếp theo một trật tự cụ thể nào.

Từ điển trong Python cũng có thể tưởng tượng giống như một cuốn từ điển Anh – Việt chẳng hạn. Bạn muốn tra từ “python” – tương ứng với khóa trong Dictionary, bạn sẽ có được phần diễn giải chính là giá trị trong Dictionary. Vậy từ điển bao gồm rất nhiều các phần tử mà mỗi phần tử đi theo cặp khóa – giá trị (key-value).

  Biến và kiểu dữ liệu cơ bản trong Python

Cách sử dụng Dictionary trong Python

Khai báo Dictionary

Dictionary trong Python được khai báo với cặp dấu ngoặc nhọn {} bao ngoài giống như với Set. Bên trong các phần tử theo cặp (khóa và giá trị) được phân tách bởi dấu phẩy, phân tách giữa khóa và giá trị của từng phần tử bởi dấu hai chấm. Cú pháp chung như sau:

dictionary_name = {key_1: value_1, key_2: value_2, ..., key_n: value_n}

Ví dụ:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
print(friend_ages["Adam"]) # Kết quả là 30

Chúng ta cũng có thể sử dụng hàm có sẵn dict() để khai báo một Dictionary.

friend_ages = dict({"Rolf": 24, "Adam": 30, "Anne": 27})
# Hoặc
friend_ages = dict([("Rolf", 24), ("Adam", 30), ("Anne", 27)])

Chú ý:

  • Khóa của Dictionary có thể là chuỗi hoặc số, khóa này là duy nhất ở từng cấp.
  • Giá trị của Dictionary có thể chuỗi, số hoặc các cấu trúc List, Tuple, Set hoặc thậm chí là Dictionary.

Một ví dụ khai báo Dictionary với giá trị phức tạp:

friends = {
  "Rolf": {
    "phone": "09382993433",
    "address": "Boston, America",
    "age": 30
  },
  "Bob": {
    "phone": "03099483832",
    "address": "London, England",
    "age": 33
  },
  "Anne": {
    "phone": "00393982224",
    "address": "Texas, America",
    "age": 25
  }
}

Truy xuất giá trị

Dictionary có thể truy xuất giá trị từng phần tử thông qua các khóa theo cú pháp:

dictionary_name[key_x]

Ví dụ, trong từ điển friends ở trên, chúng ta có thể truy xuất thông tin (giá trị) của Bob (khóa) như sau:

print(friends["Bob"]) # Kết quả là {'phone': '03099483832', 'address': 'London, England', 'age': 33}

Chú ý, mỗi phần tử trong Dictionary friends này lại là một Dictionary nên chúng ta có thể truy xuất tiếp đến tuổi tuổi của Bob như sau:

print(friends["Bob"]["age"]) # Kết quả là 33

Khi truy xuất đến các phần tử trong Dictionary, nếu khóa không tồn tại, chương trình sẽ báo lỗi KeyError.

print(friends["FirebirD"]) # Kết quả lỗi KeyError: "FirebirD"

Do vậy trước khi truy xuất giá trị một phần tử trong từ điển, chúng ta cần kiểm tra xem khóa có tồn tại hay không với toán tử in.

print("FirebirD" in friends) # Kết quả là False, FirebirD không có trong danh sách friends.

>>> Xem thêm: Kiểu dữ liệu chuỗi và định dạng chuỗi trong Python

Thay đổi giá trị

Dictionary trong Python có thể thay đổi thêm bớt các phần tử, thay đổi giá trị của các phần tử hiện có.

Thêm và cập nhật phần tử

Dictionary truy xuất thông qua khóa, do vậy khi gán giá trị cho một phần tử:

  • Khóa tồn tại thì giá trị phần tử được cập nhật.
  • Khóa không tồn tại thì Dictionary được thêm một phần tử có khóa và giá trị trong câu lệnh.
friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

# Thay đổi giá trị
friend_ages["Adam"] = 31

# Thêm một phần tử
friend_ages["Firebird"] = 37

print(friends) # Kết quả là {'Rolf': 24, 'Adam': 31, 'Anne': 27, 'Firebird': 37}

Ngoài ra chúng ta có thể sử dụng phương thức .update() để thêm hoặc chỉnh sửa giá trị nhiều phần tử vào từ điển. Trong ví dụ tiếp theo, chúng ta vừa thực hiện sửa tuổi của Rolf thành 25 và thêm một phần tử mới vào từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
new_friend_ages = {"Rolf": 25, "FirebirD": 37}
friend_ages.update(new_friend_ages)
print(friend_ages) # Kết quả là {'Rolf': 25, 'Adam': 30, 'Anne': 27, 'FirebirD': 37}

Xóa phần tử khỏi từ điển

Cũng giống như List, Dictionary có rất nhiều các phương thức có sẵn để có thể xóa một phần tử khỏi từ điển như .clear(), .pop(), .popitem() hoặc sử dụng từ khóa del.

.clear() Xóa toàn bộ các phần tử khỏi từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
friend_ages.clear()
print(friend_ages) # Kết quả là {}

.popitem() Xóa một phần tử ngẫu nhiên

.pop() Xóa một phần tử với khóa cho trước khỏi từ điển.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
friend_ages.pop("Adam")
print(friend_ages) # Kết quả là {'Rolf': 24, 'Anne': 27}

del Xóa một phần tử hoặc xóa hẳn biến chứa Dictionary.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
del friend_ages["Adam"]
print(friend_ages) # Kết quả là {'Rolf': 24, 'Anne': 27}

del friend_ages
print(friend_ages) # Kết quả lỗi NameError: name 'friend_ages' is not defined

Một số phương thức trong Dictionary

Phương thức .copy()

Phương thức này trả về một bản copy riêng biệt. Chú ý, phương thức .copy() có điểm khác so với gán biến trong Python. Chúng ta cùng xem ví dụ sau:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}
copy_friend_ages = friend_ages.copy()
new_friend_ages = friend_ages

friend_ages.clear()

print(copy_friend_ages) # Kết quả là {'Rolf': 24, 'Adam': 30, 'Anne': 27}
print(new_friend_ages) # Kết quả là {}

Như vậy, với phương thức .copy() toàn bộ bộ nhớ liên quan đến biến friend_ages được copy sang một vùng khác trong bộ nhớ, do vậy biến cũ thay đổi thì biến mới không thay đổi do tham chiếu đến vùng nhớ khác trên bộ nhớ. Còn khi gán giá trị bằng dấu =, biến đó vẫn tham chiếu đến vùng nhớ của biến cũ, nên khi biến cũ thay đổi, biến mới cũng thay đổi theo.

Phương thức .get()

Trả về giá trị một phần tử trong Dictionary với một khóa cho trước, nó giống với truy xuất giá trị tại mục 1.2 nhưng có một khác biệt nhỏ, nếu khóa không tồn tại, chương trình sẽ không báo lỗi mà trả về giá trị None.

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

print(friend_ages.get("FirebirD")) # Kết quả là None
print(friend_ages.get("Rolf")) # Kết quả là 24
print(friend_ages["FirebirD"]) # Kết quả lỗi KeyError: 'FirebirD'

Phương thức .keys() và .values()

Hai phương thức này trả về danh sách khóa và danh sách các giá trị của từ điển. Ví dụ:

friend_ages = {"Rolf": 24, "Adam": 30, "Anne": 27}

print(friend_ages.keys())
# Kết quả dict_keys(['Rolf', 'Adam', 'Anne'])

print(friend_ages.values())
# Kết quả dict_values([24, 30, 27])

So sánh List, Tuple, Set và Dictionary

Bạn đã được giới thiệu 4 cấu trúc dữ liệu có trong Python là List, Tuple, Set và Dictionary, có vẻ như hơi nhiều thứ rắm rối. Trong từng bài viết, chúng ta đã có những so sánh hai khái niệm một với nhau, giờ là lúc chúng ta tổng kết lại toàn bộ những gì đã học về 4 cấu trúc dữ liệu này:

Cách khai báo:

  • [value_1, value_2, …, value_n]: Khai báo danh sách (List)
  • (value_1, value_2, …, value_n): Khai báo Tuple
  • {value_1, value_2, …, value_n}: Khai báo tập hợp (Set)
  • {key_1:value_1, key_2:value_2, …, key_n:value_n}: Khai báo từ điển (Dictionary)

Sau khi làm quen với 4 cấu trúc List, Tuple, Set và Dictionary, có lẽ bạn sẽ rất băn khoăn: Nên lựa chọn cấu trúc nào cho phù hợp với chương trình của bạn? Trước khi đến với câu trả lời, tôi khuyên bạn hãy đọc thật kỹ lại kiến thức từng cấu trúc này:

Sau đó, chúng ta cùng đúc kết để có được câu trả lời cho: Khi nào dùng List, Tuple, Set hay Dictionary trong Python?

  • Sử dụng List khi muốn có dữ liệu truy xuất theo thứ tự (vị trí của phần tử tăng dần từ 0), dữ liệu List ở dạng đơn giản và thay đổi thường xuyên.
  • Sử dụng Set khi muốn dữ liệu là duy nhất và dễ dàng thực hiện các phép toán tập hợp như phép giao, hợp, trừ.
  • Sử dụng Tuple khi dữ liệu không thay đổi và cần tốc độ xử lý.
  • Sử dụng Dictionary khi dữ liệu thay đổi liên tục, có sự liên kết logic giữa khóa và giá trị và một điểm nhấn quan trọng là muốn truy xuất dữ liệu nhanh thông qua khóa.

Bài viết gốc được đăng tải tại allaravel.com

Xem thêm Việc làm python lương cao hấp dẫn trên TopDev