(5) là int, nhưng (5,) là tuple?!
Hiện tượng lạ
Phần tiêu đề “Hiện tượng lạ”Hãy xem đoạn code sau và đoán xem kết quả sẽ là gì:
a = (5)b = (5,)
print(type(a))print(type(b))Kết quả:
<class 'int'><class 'tuple'>What the Python?! Tại sao (5) lại là int trong khi (5,) lại là tuple? 🤔
Giải thích
Phần tiêu đề “Giải thích”Dấu ngoặc đơn trong Python
Phần tiêu đề “Dấu ngoặc đơn trong Python”Trong Python, dấu ngoặc đơn () không tạo ra tuple! Điều tạo ra tuple chính là dấu phẩy ,!
# Dấu ngoặc đơn chỉ là toán tử nhóm (grouping operator)a = (5) # Giống như a = 5b = (2 + 3) # Giống như b = 2 + 3c = (10) # Giống như c = 10
print(type(a), type(b), type(c)) # <class 'int'> <class 'int'> <class 'int'>Dấu phẩy mới tạo tuple
Phần tiêu đề “Dấu phẩy mới tạo tuple”# Dấu phẩy tạo ra tuplex = 5, # Tuple với 1 phần tửy = 5, 10 # Tuple với 2 phần tửz = 5, 10, 15 # Tuple với 3 phần tử
print(type(x)) # <class 'tuple'>print(type(y)) # <class 'tuple'>print(type(z)) # <class 'tuple'>
print(x) # (5,)print(y) # (5, 10)print(z) # (5, 10, 15)Dấu ngoặc đơn chỉ để dễ đọc
Phần tiêu đề “Dấu ngoặc đơn chỉ để dễ đọc”Dấu ngoặc đơn () trong tuple chỉ giúp code dễ đọc hơn, nhưng không bắt buộc (trừ tuple rỗng):
# Các cách tạo tuple giống nhautuple1 = (1, 2, 3)tuple2 = 1, 2, 3
print(tuple1 == tuple2) # True
# Tuple rỗng BẮT BUỘC dùng ()empty = ()print(type(empty)) # <class 'tuple'>Tại sao lại thiết kế như vậy?
Phần tiêu đề “Tại sao lại thiết kế như vậy?”-
Dấu ngoặc đơn đã có mục đích riêng: Trong toán học và lập trình,
()được dùng để nhóm các biểu thức, ví dụ(2 + 3) * 4 -
Tuple là sequence của nhiều giá trị: Dấu phẩy
,thể hiện việc “liệt kê” các giá trị -
Tính nhất quán với unpacking:
a, b = 1, 2 # Tuple unpacking, không cần ()
Các trường hợp dễ nhầm
Phần tiêu đề “Các trường hợp dễ nhầm”1. Tạo tuple 1 phần tử
Phần tiêu đề “1. Tạo tuple 1 phần tử”# SAI - Không phải tuplewrong = (42)print(type(wrong)) # <class 'int'>
# ĐÚNG - Cần dấu phẩycorrect = (42,)print(type(correct)) # <class 'tuple'>
# ĐÚNG - Không cần ngoặc đơn cũng đượcalso_correct = 42,print(type(also_correct)) # <class 'tuple'>2. Trong function return
Phần tiêu đề “2. Trong function return”def get_coordinates(): return 10, 20 # Trả về tuple (10, 20)
def get_single_value(): return (42) # Trả về int 42, không phải tuple!
def get_single_tuple(): return (42,) # Trả về tuple (42,)
print(type(get_coordinates())) # <class 'tuple'>print(type(get_single_value())) # <class 'int'>print(type(get_single_tuple())) # <class 'tuple'>3. Trong function arguments
Phần tiêu đề “3. Trong function arguments”# Truyền 1 argument là intprint((5)) # In ra: 5
# Truyền 1 argument là tupleprint((5,)) # In ra: (5,)Khi nào BẮT BUỘC dùng dấu ngoặc đơn?
Phần tiêu đề “Khi nào BẮT BUỘC dùng dấu ngoặc đơn?”1. Tuple rỗng
Phần tiêu đề “1. Tuple rỗng”empty = () # Bắt buộc phải có ()2. Tránh nhầm lẫn trong expressions
Phần tiêu đề “2. Tránh nhầm lẫn trong expressions”# Không có ngoặc - lỗi cú pháp# result = 1, 2 + 3, 4 # Có thể gây hiểu lầm
# Có ngoặc - rõ ràng hơnresult = (1, 2) + (3, 4) # Nối 2 tuplesprint(result) # (1, 2, 3, 4)3. Trong list/dict comprehensions
Phần tiêu đề “3. Trong list/dict comprehensions”# Cần ngoặc để phân biệt với generator expressionlist_of_tuples = [(x, x**2) for x in range(5)]print(list_of_tuples) # [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]Thực hành
Phần tiêu đề “Thực hành”Hãy đoán xem type() của các biến sau:
# Thử đoán trước khi chạy!var1 = (10)var2 = (10,)var3 = 10,var4 = ()var5 = (10, 20)var6 = 10, 20var7 = (10 + 5)var8 = (10 + 5,)Xem đáp án
print(type(var1)) # <class 'int'>print(type(var2)) # <class 'tuple'>print(type(var3)) # <class 'tuple'>print(type(var4)) # <class 'tuple'>print(type(var5)) # <class 'tuple'>print(type(var6)) # <class 'tuple'>print(type(var7)) # <class 'int'>print(type(var8)) # <class 'tuple'>Tóm tắt
Phần tiêu đề “Tóm tắt”| Code | Kiểu dữ liệu | Giải thích |
|---|---|---|
(5) |
int |
Chỉ là dấu ngoặc nhóm |
(5,) |
tuple |
Dấu phẩy tạo tuple |
5, |
tuple |
Dấu phẩy tạo tuple (không cần ngoặc) |
() |
tuple |
Tuple rỗng (bắt buộc có ngoặc) |
(1, 2) |
tuple |
Tuple 2 phần tử |
1, 2 |
tuple |
Tuple 2 phần tử (không cần ngoặc) |
Ghi nhớ
Phần tiêu đề “Ghi nhớ”Trong Python, dấu phẩy
,tạo tuple, không phải dấu ngoặc đơn()!
Dấu ngoặc đơn chỉ để làm code dễ đọc hơn và bắt buộc cho tuple rỗng.