Học bằng cách đọc theo thứ tự

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

list vs tuple
list[1, 2, 3]khả biếntuple(1, 2, 3)bất biếnkhai báotính chấtkhai báotính chất

Chỉ có loại dấu ngoặccó 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ữ ( ).

Khai báo một tuple và lấy giá trị ra.

① Tạo colors = ("red", "green", "blue") và dùng print() để hiển thị màu đầu tiêncuối cùng.

② In colors[0:2], rồi dùng type() để xác nhận rằng kết quả slicing vẫn là tuple.

(Nếu code chạy đúng, phần giải thích sẽ hiện ra.)

Python Editor

Chạy code để xem đầu ra

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ử»«bỏ cả một tuple mới vào biến». Cái đầu là không được; cái sau thì OK.

« Sửa phần tử » vs « Tráo hộp »
t = (1,2,3)t[0] = 9TypeErrort = (1,2,3)t = (4,5,6)trỏ sangtuple mớiphần tửlỗigán lạiOK

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.

Cùng xác nhận xem sửa phần tử tuple có thật sự gây lỗi không.

① Chạy code bên dưới nguyên xi. Bạn sẽ thấy một TypeError.

② Sau khi thấy lỗi, comment dòng my_tuple[0] = 9 (thêm # đầu dòng), rồi thêm my_tuple = (9, 2, 3) và in my_tuple. Lần này không bị lỗi.

Python Editor

Chạy code để xem đầu ra

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ếtGhi nhớ
Ghépt1 + t2Trả 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(...).

Lấy thông tin ra từ tuple các ngày trong tuần.

days = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") đã được chuẩn bị.

① Dùng days.index("Fri") với print() để in vị trí của "Fri".

② Tạo weekend = ("Sat", "Sun"), rồi in days + weekend để xem ghép ra cái gì (có trùng phần tử cũng không sao).

Python Editor

Chạy code để xem đầu ra

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éndùng làm khóa của dict.

Giải nén — tách thành nhiều biến trong một dòng
coord=(135, 35)lng, lat= coordlng=135lat=35gángiải nén

Đặ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.

Giải nén một màu RGB.

rgb = (200, 100, 50) đã có sẵn.

① Dùng giải nén để lấy các giá trị đỏ / xanh lá / xanh dương ra ba biến r, g, b.

② Dùng print() để in r, g, b mỗi biến một dòng.

Python Editor

Chạy code để xem đầu ra

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

tuple có thể làm khóa dict
(135,35)tuplekhóa củadictOK[135,35]listkhóa củadictTypeError
# 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'

Tạo một dict liên kết tọa độ với tên thành phố.

① Tạo dict cities trong đó khóa (35.0, 139.0)"Tokyo", và khóa (34.7, 135.5)"Osaka".

② In cities[(35.0, 139.0)] để xác nhận lấy được Tokyo.

③ Tra (0.0, 0.0) bằng .get(), truyền "Không rõ" làm tham số thứ hai, và xác nhận rằng vẫn chạy an toàn kể cả khi khóa không tồn tại.

Python Editor

Chạy code để xem đầu ra

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.

QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Trong các lựa chọn sau, lựa chọn nào khai báo đúng một tuple?

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 lnglat là gì?