Câu 1Trong các lựa chọn sau, lựa chọn nào khai báo đúng một tuple?
Cách dùng tuple trong Python
Hiểu kiểu tuple trong Python: khai báo bằng ngoặc đơn, tính bất biến và sự khác biệt với list khi cần dữ liệu cố định.
Tuple là gì — phiên bản « không thể thay đổi » của list
Tuple (tuple) cho phép bạn gom nhiều giá trị lại trong một biến duy nhất. Nó rất giống list đã học ở bài trước, nhưng điểm khác biệt chính là sau khi tạo rồi thì không thể thay đổi nội dung nữa.
Nếu list là một cái hộp bạn định sửa đi sửa lại (như danh sách mua sắm), thì tuple là cái hộp chốt một lần rồi để yên — hãy nghĩ đến tọa độ (x, y) hay màu RGB (255, 0, 0).
Chỉ có loại dấu ngoặc và có thể thay đổi hay không là khác nhau; vai trò — gom nhiều giá trị lại — thì giống nhau.
Nếu thay đổi, dùng list; nếu cố định, dùng tuple là quy tắc đơn giản.
Để khai báo, chỉ cần đặt các giá trị trong ( và ), ngăn cách bằng dấu phẩy. Chỗ list dùng [ ], tuple dùng ( ).
Truy cập phần tử (chỉ số và slicing) hoạt động giống hệt với list: [0] lấy phần tử đầu, [-1] lấy phần tử cuối, [1:3] lấy một đoạn.
# Khai báo tuple
fruits = ("apple", "banana", "lemon")
print(fruits) # ('apple', 'banana', 'lemon')
print(type(fruits)) # <class 'tuple'>
print(fruits[0]) # apple
print(fruits[-1]) # lemon
print(fruits[1:]) # ('banana', 'lemon') ← kết quả cắt cũng là tuple
# Trộn nhiều kiểu vẫn OK
profile = ("Minh", 28, 165.5)
Tuple một phần tử cần dấu phẩy ở cuối
Nếu bạn viết fruits = ("apple"), thì đây là một chuỗi, không phải tuple. ( ) cũng được dùng làm dấu ngoặc trong toán học, nên Python không phân biệt được khi chỉ có một giá trị bên trong.
Để tạo tuple một phần tử, thêm dấu phẩy ở cuối như ("apple",).
Python cũng cho phép bỏ hẳn dấu ngoặc và viết kiểu 1, 2, 3 như một tuple, nhưng để dễ đọc thì vẫn nên giữ ( ).
Bất biến — « sửa phần tử » và « tráo cả hộp » là hai chuyện khác nhau
Tuple là kiểu bất biến (không thể thay đổi). Sau khi tạo, bạn không thể ghi đè, thêm, hay xóa phần tử.
Điều hay gây nhầm ở đây là phân biệt giữa «đổi phần tử» và «bỏ cả một tuple mới vào biến». Cái đầu là không được; cái sau thì OK.
t[0] = 9 cố sửa trực tiếp nội dung, nên lỗi.
t = (4, 5, 6) chỉ trỏ biến sang tuple mới, nên OK.
Ghép và phương thức (count / index)
Bạn có thể tạo tuple mới bằng cách ghép hai tuple. Dùng + để ghép trả về một tuple hoàn toàn mới.
Không có nhiều phương thức — hai cái bạn thật sự dùng là count và index. Cảm giác giống hệt trên list.
| Muốn làm gì | Cách viết | Ghi nhớ |
|---|---|---|
| Ghép | t1 + t2 | Trả về tuple mới; bản gốc không đổi |
| Thêm một phần tử | t + (x,) | Đừng quên dấu phẩy cuối |
| Đếm giá trị | t.count(x) | x xuất hiện bao nhiêu lần |
| Tìm vị trí | t.index(x) | Vị trí đầu tiên x xuất hiện |
fruits = ("apple", "banana", "lemon")
# Ghép (trả về tuple mới)
more = fruits + ("grape",)
print(more) # ('apple', 'banana', 'lemon', 'grape')
print(fruits) # ('apple', 'banana', 'lemon') ← bản gốc không đổi
# count và index
nums = (1, 2, 2, 3, 2, 4)
print(nums.count(2)) # 3 (có ba số 2)
print(nums.index(3)) # 3 (3 đứng thứ 4 = index 3)
# Chuyển đổi giữa list và tuple
list_fruits = list(fruits) # ['apple', 'banana', 'lemon']
tuple_fruits = tuple(list_fruits) # ('apple', 'banana', 'lemon')
Nếu cần sửa nhiều, đổi sang list
Tuple dành cho «giá trị hầu như không động tới», nên không hợp khi bạn phải thêm/xóa phần tử liên tục. Khuôn mẫu tiêu chuẩn: đổi sang list bằng list(t) → chỉnh → nếu cần thì chuyển lại bằng tuple(...).
Giải nén và khóa dict — những việc chỉ tuple mới làm được
Có hai thứ tuple làm được mà list không làm được: giải nén và dùng làm khóa của dict.
Đặt các tên biến cách nhau bằng dấu phẩy ở bên trái, và từng phần tử của tuple sẽ đi thẳng vào từng biến.
Thứ tự khớp theo vị trí, và số biến phải bằng số phần tử.
# Giải nén
coord = (135.0, 35.0)
longitude, latitude = coord
print(longitude) # 135.0
print(latitude) # 35.0
# Cũng có thể giải nén từ literal
r, g, b = (255, 128, 0)
print(r, g, b) # 255 128 0
# Thủ thuật thường gặp: hoán đổi hai giá trị trong một dòng
a, b = 1, 2
a, b = b, a
print(a, b) # 2 1
Giá trị trả về của hàm cũng là tuple (xem trước)
Hàm trong Python có thể trả về nhiều giá trị với return a, b, và chúng sẽ tự động được đóng gói thành tuple. Bên gọi viết x, y = func() sẽ giải nén thành hai biến. Chương về hàm sẽ nói sau, nên ở đây không đi sâu — nhưng nhớ rằng «nhiều giá trị trả về và giải nén đi cùng nhau» sẽ giúp bạn hiểu chương đó nhanh hơn.
Điểm mạnh còn lại là tuple có thể dùng làm khóa của dict. list không thể làm khóa dict, nhưng tuple thì được. Rất hữu ích khi bạn muốn dùng tổ hợp nhiều giá trị làm một khóa duy nhất — ví dụ, ánh xạ tọa độ sang tên quốc gia.
# dict với khóa tuple
country = {
(135.0, 35.0): "Japan",
(-77.0, 38.9): "USA",
}
print(country[(135.0, 35.0)]) # Japan
print(country.get((0.0, 0.0), "Không rõ")) # Không rõ
# list không làm khóa được
# bad = {[135.0, 35.0]: "Japan"} # TypeError: unhashable type: 'list'
Trong bài này, xoay quanh sự khác biệt với list, bạn đã học cách khai báo tuple, ý nghĩa của bất biến, ghép và count / index, cùng giải nén và khóa dict.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Với t = (1, 2, 3), lựa chọn nào không gây lỗi?
Câu 3Với coord = (135.0, 35.0), cách đơn giản nhất để tách hai giá trị vào biến lng và lat là gì?