# data[].attributes.body
1. Sơ lược về Dictionary:

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 ở ngoài cuộc sống đời thường của chúng ta. Nhưng cấu trúc dữ liệu Dictionary 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).

Ví dụ: bạn muốn tra từ “handsome” (được xem là key trong Dictionary), thì sau đó bạn sẽ nhận được phần diễn giải cho từ “handsome”, chính là giá trị trong Dictionary.

2. Cách khai báo:

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}

dictionary_name = dict ({“key_1”: value_1, “key_2”: value_2,..., ”key n”: value n})

dictionary_name = dict([("key_1", value_1), ("key_2", value 2), ("key_3", value 3)])

Ví dụ:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

3. Truy cập các phần tử:

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 ở trên, chúng ta có thể truy xuất số điểm (giá trị) của Đăng (khóa) như sau:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

print(do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10["Đăng"])

#Kết quả là: 1000

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(do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10["Gia"])

# Output: invalid character, Gia không có trong danh sách

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 ("Gia" in  do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

# Output: invalid character (do Gia không có trong danh sách

4. Các phương thức của Dictionary:

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

Ví dụ:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

# Thay đổi giá trị
do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 [“Danh”] = 5

# Thêm một phần tử
do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 [“Gia”] = 9

print (do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

# Output: do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 5, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000, “Gia”: 9}

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.

Ví dụ:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

new_do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Gia”: 9}

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10.update(new_do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

print (do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

# Output:
 {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000, “Gia”: 9}

b. Xóa phần tử:

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.

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10.clear()

print(do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)
# Output: {}

*.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.
Ví dụ:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10.pop("Fong")

print(do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

# Output:
 {“Danh”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

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

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

del do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 [“Minh_Nhật”]

print(do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10)

# Output: {“Danh”: 10, “Fong”: 10, ”Đăng”: 1000}

c. 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:

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

dict1= do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10

dict2= do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10.copy()

do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10["Duy"]=5

print("dict1:", dict1)
print("dict2:", dict 2)

# Output:
dict1= do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000, "Duy": 5}

dict2= do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10 = {“Danh”: 10, “Fong”: 10, “Minh_Nhật”: 100, ”Đăng”: 1000}

Như vậy, với phương thức .copy() toàn bộ bộ nhớ liên quan đến biến do_dep_trai_cua_nam_sinh_11A1_tren_thang_diem_10

đượ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

d. 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ị 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.

capital_of_country = {"USA": Washington, "Vietnam": Hanoi, "Japan": Tokyo}

print(captial_of_country.get("Senegal"))

# Output: None

print(capital_of_country.get("USA"))

# Output: Washington

e. 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ụ:

Nickname_of_11A1_students = {"NMinh": Rebel, "Thành": Việt kiều, "Gia": Sir}

print(Nickname_of_11A1_students.keys())

# Output: dict_keys(['NMinh', 'Thành', 'Gia'])

print(Nickname_of_11A1_students.values())

# Output: dict_values([Rebel, Việt kiều, Sir])

5. Những điều cần lưu ý khi sử dụng Dictionary:

- 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
- 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
- Khi thêm hoặc tạo Dict, tất cả các mục nhập phải ở định dạng cặp khóa: giá trị. Nếu khóa hoặc giá trị bị thiếu, sẽ thông báo lỗi.
- Nếu một cặp khóa và giá trị được thêm vào Dict và khóa đã tồn tại trong Dict, khóa và giá trị cũ sẽ bị thay thế bởi khóa và giá trị mới.
- Các giá trị chỉ có thể được cập nhật khi chỉ định rõ khóa liên quan.
- Khi xóa một phần tử (là cặp khóa:giá trị) thì cả 2 sẽ xóa cùng nhau.
- Danh sách không thể được sử dụng làm khóa.
- Trong Dict, nếu có 2 khóa trùng tên, khi truy xuất, giá trị của khóa cuối cùng sẽ được chọn

# data[].attributes.body
Bài 1: Cho dictionary sau:

car = { "brand": "Ford",
 "model": "Mustang",
 "year": 1964}

Hãy in ra câu “The Ford Mustang is made in 1964” sử dụng dictionary trên.

Đáp án:

print("The",car["brand"],car["model"],"is made in",car["year"])

Bài 2: Câu lệnh này sẽ in ra gì?

car = {
"brand": "Ford",
  "model": "Mustang",
  "year": 1964,
  "year": 2020
}
print(car)

Đáp án:
{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}

Bài 3: Cho dictionary sau, hãy xuất ra số điện thoại của Anne:

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
  }
}

Đáp án:

print(friends["Anne"]["phone"])

# data[].attributes.headline
Phân biệt Tuple, Dictionary, Set (Thái Hòa)

# data[].attributes.subject
Phân biệt Tuple, Dictionary, Set (Thái Hòa)

# data[].attributes.body
Điểm khác biệt:

Tuple: dùng để chứa dữ liệu trong 1 biến, dữ liệu được sắp xếp theo thứ tự nên truy phần tử được, không thể thay đổi phần tử, cho phép lặp lại phần tử. Được khai báo trong ngoặc ()

Set: dùng để chứa dữ liệu trong 1 biến, dữ liệu không sắp xếp theo thứ tự, không thể thay đổi dữ liệu nhưng add hoặc remove phần tử trong set vẫn được, không được đánh số nên không thể truy phần tử theo cách index, không cho phép lặp lại phần tử. Được khai báo trong ngoặc {}

Dictionary: dùng để chứa dữ liệu đi theo cặp trong 1 biến, được sắp xếp theo thứ tự (phiên bản python 3.7 trở đi) nên truy phần tử được, có thể thay đổi dữ liệu, không cho phép lặp lại phần tử, nếu lặp phần tử sẽ thay thế phần tử bị lặp bằng cái mới. Được khai báo trong ngoặc {}

# data[].attributes.body
1. Cách khai báo:
Tuple trong Python được khai báo bằng cách đặt các phần tử trong dấu ngoặc (), được ngăn cách giữa các phần tử với nhau bằng dấu “,”.

traicay= ("quýt", "cam", "mận", "ổi")
print (traicay)

2. Truy cập các phần tử:

Sử dụng toán tử index [] để truy cập vào một phần tử của tuple. Index bắt đầu từ 0, nên một tuple có 6 phần tử sẽ có index từ 0 .

tupleA = ('p','e','r','m','i','t')
 print(tupleA[0])   #Output: 'p'
 print(tupleA[5])   #Output: 't'

Chúng ta có thể truy cập phần tử của Tuple bằng dấu “:” của toán tử cắt (Slicing).

tupleA = ('p','r','o','g','r','a','m','i','z')
 # Output: ('r', 'o', 'g')
print(tupleA[1:4])
 # Output: ('p', 'r')
print(tupleA[:-7])
# Output: ('i', 'z')
print(tupleA[7:])
# Output: ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
print(tupleA[:])

3. Các hàm, phương thức và toán tử:
a. Phương thức:

Count(x): đếm số phần tử trong tuple.

Index(x): trả về giá trị index đầu tiên mà nó gặp trong tuple.

nvs = ('lavabo', 'bồn cầu', 'bồn tắm', 'máy nước nóng', '',)
print(nvs.count('bồn cầu'))
# Output: 2
print(nvs.index('máy nước nóng'))
# Output: 3

b. Hàm:

Hàm del: ta không thể dùng hàm del để xoá một phần tử trong tuple mà có thể xoá toàn bộ tuple đi.

tupleB = ('p', 'r', 'o', 'g', 'r', 'a', 'm', 'i', 'z')
del tupleB
# Xóa toàn bộ tuple

Hàm len: có tác dụng như hàm len đối với list, trả danh sách về độ dài của nó.

tupleC = (1, 2, 3, [6, 5])
len (tupleC)
# Output:4

Hàm max, min: Có vai trò trả tuple về giá trị lớn nhất, nhỏ nhất trong danh sách đó.

A = ( 3 , 1 , 2 , 5 , 4 , 6 )
       max (A)     #Output: 6
       min (A)      #Output: 1

Hàm sum: Hàm này trả về tổng số các mục trong tuple

A = ( 3 , 1 , 2 , 5 , 4 , 6 )
sum(A)
# Output: 21

Hàm sort: Hàm này trả về một phiên bản đã được sắp xếp của bộ tuple. Hàm này sẽ sắp xếp giá trị theo thứ tự tăng dần và không sửa đổi những giá trị nguyên gốc trong Python.

VD: A = ( 3 , 1 , 2 , 5 , 4 , 6 )
sort (A)
# Output:[1,2,3,4,5,6]

c. Toán tử:
Có thể sử dụng toán tử “+” để kết hợp hai tuple, hay có thể sử dụng “*” để lặp lại các phần tử trong tuple một số lần nhất định.

# Output: (1, 2, 3, 4, 5, 6)
print((1, 2, 3) + (4, 5, 6))
# Repeat
# Output: ('đẹp trai', 'đẹp trai', 'đẹp trai')
print((“đẹp trai",) * 3)

4. Những lưu ý khi sử dụng tuple:

Nếu muốn lập một tuple chỉ có một giá trị, ta phải thêm dấu phẩy vào.

tupleD = (1,);

Bản thân tuple là một danh sách không hỗ hợ xoá hay thêm bớt phần tử, vì thế khi sửa hay xoá phần tử tuple sẽ bị lỗi.

# data[].attributes.body
1. Cách khai báo:

Set là một cấu trúc dữ liệu dạng đa giá trị trong Python

Sử dụng các dấu ngoặc nhọn trong báo Set

vd = {“kha”,“kho”,“khao”)
print(vd)

2. Truy cập các phần tử:

Không thể truy cập các phần tử trong một Set bằng cách sử dụng chỉ mục

Có thể sử dụng vòng lặp for để truy cập các phần tử của một Set

Ví dụ:

Duyệt các phần tử của Set và in các giá trị ra màn hình

setFood = {"burger", "pho", "rice"}
for x in setFood:
    print(x)
# Output:
burger
pho
rice

Có thể sử dụng từ khóa in để kiểm tra xem phần tử có tồn tại trong Set hay không

setFood = {"burger", "pho", "rice"}
x = "burger" in setFood
print(x)
# Output: True

3. Các phương thức, hàm và toán tử:
a. Phương thức:

Phương thức add dùng để thêm phần tử vào “vị trí bất kỳ” trong tập hợp

vd = {"kha","kho","khoa"}
vd.add("khanh")
print(vd)
# Output: {"khoa","kho","khanh","kha"}

Phương thức remove dùng để loại bỏ một phần tử trong tập hợp

vd = {"kha","kho","khoa"}
vd.remove("kho")
print(vd)
# Output: {"khoa","kha"}

Lưu ý: nếu phần tử không tồn tại thì chương trình sẽ báo lỗi

Phương thức discard cũng dùng để loại bỏ một phần tử trong tập hợp

vd = {"kha","kho","khoa"}
vd.discard("kho")
print(vd)
# Output: {"khoa","kha"}

Lưu ý: nếu phần tử không tồn tại thì chương trình sẽ không báo lỗi

Phương thức pop dùng để loại bỏ 1 phần tử “bất kỳ” trong tập hợp

vd = {"kha","kho","khoa"}
vd.pop()
print(vd)
# Output: {"khoa","kho"}

Phương thức clear dùng để loại bỏ tất cả các phần tử trong tập hợp

vd = {"kha","kho","khoa"}
vd.clear()
print(vd)
# Output: set()

Phương thức update  để thêm nhiều phần tử.  Chú ý, đầu vào có thể là một Set, một List hoặc một Tuple.

friends = {"kha","kho","khoa"}
friends.update(["khi","khia"],{"khoi", "khui"},("khai","kheo"))
print(friends)
# Output: {'khia', 'khoi', 'kheo', 'kho', 'khui', 'khoa', 'khi', 'khai', 'kha'}

Chú ý: không sử dụng chuỗi để cập nhật vì chuỗi sẽ được coi là một danh sách các ký tự

vd = {"kha","kho","khoa"}
vd.update("cat")
print(vd)
# Output: {"t","khoa","kho","a","c"}

Chú ý: có thể sử dụng phương thức .add() hoặc có chuyển chuỗi thành Set, List hoặc Tuple có 1 phần tử

vd = {"kha","kho","khoa"}
vd.update(["cat"])
print(vd)
# Output: {"cat","khoa","kho"}

b. Hàm:
Hàm frozenset, kết quả trả về là một tập hợp (Set) không thể thay đổi (thực hiện các phương thức add, remove, update sẽ báo lỗi)

vd = {"kha","kho","khoa"}
frozen_vd = frozenset(vd)
vd.add("khanh")
print(vd)
#Output: Error

c. Phép toán:

Phép union hợp của hai tập hợp cho kết quả là tất cả các phần tử trong hai tập hợp, chú ý phần tử nào lặp lại sẽ chỉ xuất hiện 1 lần trong tập kết quả.

nguoideptrai = {"kho", "khoa", "kha"}
nguoitrithuc = {"kha", "khoi"}
tatcanguoi = nguoideptrai.union(nguoitrithuc)
print(tatcanguoi)
# Output: {'kho', 'khoa', 'kha', 'khoi'}

Phép difference hiệu của một tập A trừ đi một tập B cho kết quả là tất các phần tử thuộc A nhưng không thuộc B.

nguoideptrai = {"kho", "khoa", "kha"}
nguoitrithuc = {"kha", "khoi"}
depkhongtrithuc= nguoideptrai.difference(nguoitrithuc)
print(depkhongtrithuc)
# Output: {'kho','khoa'}

Phép Symmetric difference cho kết quả là hiệu đối xứng của hai tập hợp (Hiệu đối xứng của hai tập A và B được kết quả là tập hợp các phần tử thuộc cả A và B nhưng không đồng thời thuộc cả tập A và B)

nguoideptrai = {"kho", "khoa", "kha"}
nguoitrithuc = {"kha", "khoi"}
depkhongtrithuc= nguoideptrai.symmetric_difference(nguoitrithuc)
print(depkhongtrithuc)
# Output: {'kho','khoa','khoi'}

Phép intersection giao hai tập hợp cho kết quả là các phần tử đồng thời thuộc cả hai tập hợp (tập hợp nào đứng trước cũng được).

nguoideptrai = {"kho", "khoa", "kha"}
nguoitrithuc = {"kha", "khoi"}
deptraivatrithuc= nguoideptrai.intersection(nguoitrithuc)
print(deptraivatrithuc)
# Output: {'kha'}

Phương thức .difference_update() là sự kết hợp của .difference() và .update(), thực hiện phép trừ tập hợp trước, được kết quả như thế nào sẽ cập nhật vào tập hợp đích

A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
A.difference_update(B)
print(A)
# Output: {1, 2}

Phương thức .symmetric_difference_update() là sự kết hợp của .symmetric_difference() và .update(), thực hiện phép trừ đối xứng 2 tập hợp trước, kết quả sẽ cập nhật vào tập hợp đích.

A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
A.symmetric_difference_update(B)
print(A)
# Output: {1, 2, 5, 6}

Phép isdisjoint Trả về True nếu hai tập hợp không giao nhau, tức là hai tập hợp không có phần tử chung

A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
print(not A.isdisjoint(B))
# Output: True

Phép issubset trả về True nếu tập này còn tập con của tập đích (tập trong ngoặc)

A = {3, 4}
B = {3, 4, 5, 6}
print(A.issubset(B))
# Output: True

Phép issuperset trả về True nếu tập này là tập cha của tập đích (tập trong ngoặc)

A = {3, 4}
B = {3, 4, 5, 6}
print(A.issuperset(B))
# Output: False

4. Những điều cần lưu ý khi dùng Set trong Python:

Các phần tử không có thứ tự

Các phần tử không bị lặp lại

Có thể thay đổi (thêm bớt phần tử) nhưng các phần tử của tập hợp phải ở dạng không thể thay đổi (tức là xác định được dung lượng bộ nhớ ngay lúc khai báo).