Trong quá trình xây dựng ứng dụng Python, việc xử lý nhiều điều kiện khác nhau thường tạo ra các khối lệnh if-elif-else
phức tạp, khó đọc và bảo trì. Câu lệnh match-case
, được giới thiệu từ phiên bản Python 3.10, cung cấp một giải pháp mới, giúp code trở nên rõ ràng và dễ quản lý hơn. Bài viết này sẽ hướng dẫn bạn cách tận dụng sức mạnh của match-case để đơn giản hóa logic và nâng cao chất lượng code Python.
Câu lệnh match-case trong Python là gì?
Câu lệnh match-case
trong Python là lệnh dùng để kiểm tra và xử lý các giá trị khác nhau. Cụ thể, lệnh này sẽ lấy một biểu thức và so sánh giá trị của nó với các mẫu (pattern) được định nghĩa trong các khối case. Khi một mẫu khớp, khối lệnh tương ứng sẽ được thực thi. Không chỉ dừng lại ở việc so sánh, match-case
còn cho phép bạn trích xuất các phần tử từ giá trị và gán các phần tử này vào các biến, giúp việc xử lý dữ liệu trở nên linh hoạt hơn.
Câu lệnh match-case
xuất hiện từ phiên bản Python 3.10, và nó có nét tương đồng với cấu trúc switch-case mà bạn có thể đã từng thấy trong C/C++ hoặc Java. Tuy nhiên, match-case
không đơn thuần là một phiên bản khác của switch-case. Câu lệnh này gần với kỹ thuật khớp mẫu mà chúng ta thường thấy trong các ngôn ngữ như Rust hoặc Haskell hơn, mang đến nhiều khả năng so khớp phức tạp và tinh tế.
Cú pháp của câu lệnh match-case trong Python
Dưới đây là cú pháp của câu lệnh match-case trong Python:
match variable_name:
case 'pattern 1' : statement 1
case 'pattern 2' : statement 2
...
case 'pattern n' : statement n
Ví dụ về câu lệnh match-case trong Python
Đoạn code dưới đây sẽ minh họa cho cách sử dụng một hàm có tên weekday()
. Hàm này nhận vào một số nguyên (ví dụ: 0, 1, 2, …) và đối chiếu số đó với các giá trị tương ứng với thứ trong tuần. Kết quả trả về là tên thứ tương ứng.
def weekday(n):
match n:
case 0: return "Monday"
case 1: return "Tuesday"
case 2: return "Wednesday"
case 3: return "Thursday"
case 4: return "Friday"
case 5: return "Saturday"
case 6: return "Sunday"
case _: return "Invalid day number"
print (weekday(3))
print (weekday(6))
print (weekday(7))
Sau khi chạy đoạn code trên, bạn sẽ thấy kết quả như sau:
Thursday
Sunday
Invalid day number
Giải thích chi tiết:
def weekday(n):
: Dòng này định nghĩa một hàm tên làweekday
, hàm này sẽ nhận một tham số đầu vào làn
(số nguyên).match n:
: Đây là cấu trúcmatch case
mới trong Python, giúp kiểm tra giá trị của biếnn
. Nó tương tự như cấu trúcswitch case
ở một số ngôn ngữ lập trình khác.case 0: return "Monday"
: Nếun
có giá trị là 0, hàm sẽ trả về chuỗi “Monday” (Thứ Hai). Tương tự, các case khác tương ứng với các thứ trong tuần.case _: return "Invalid day number":
Dòng này đặc biệt. Dấu gạch dưới_
hoạt động như một “lệnh bắt tất cả”. Nếu không có case nào ở trên khớp với giá trị củan
, thìcase _
sẽ được thực thi, và hàm sẽ trả về chuỗi “Invalid day number” (Số ngày không hợp lệ).print(weekday(3))
,print(weekday(6))
,print(weekday(7))
: Các dòng này gọi hàmweekday()
với các giá trị khác nhau và in ra kết quả. Như bạn thấy,weekday(3)
cho kết quả là “Thursday” (Thứ Năm),weekday(6)
cho kết quả “Sunday” (Chủ nhật), vàweekday(7)
trả về “Invalid day number” (vì số 7 không đại diện cho một ngày nào trong tuần).
Kết hợp các trường hợp trong cậu lệnh match-case
Đôi khi, bạn sẽ gặp tình huống cần thực hiện cùng một hành động cho nhiều trường hợp khác nhau. Trong Python, bạn có thể kết hợp các trường hợp này bằng toán tử “OR”, được biểu diễn bằng ký hiệu|
.
Đoạn code dưới đây minh họa cách kết hợp các trường hợp trong câu lệnh match. Định nghĩa một hàm có tên access() và nhận một tham số là một chuỗi, đại diện cho tên người dùng. Đối với người dùng là “admin” hoặc “manager”, hệ thống sẽ cấp toàn quyền truy cập, còn đối với “Guest”, quyền truy cập sẽ bị hạn chế; và với tất cả người dùng còn lại, sẽ không có quyền truy cập nào.
def access(user):
match user:
case "admin" | "manager": return "Full access"
case "Guest": return "Limited access"
case _: return "No access"
print (access("manager"))
print (access("Guest"))
print (access("Bo"))
Khi chạy đoạn code trên, kết quả sẽ như sau:
Full access
Limited access
No access
Giải thích chi tiết:
def access(user):
: Định nghĩa hàmaccess
nhận tham sốuser
là một chuỗi (tên người dùng).match user:
: Bắt đầu câu lệnhmatch
để so sánh giá trị của biếnuser
.case "admin" | "manager": return "Full access"
: Điểm quan trọng ở đây. Thay vì viết haicase
riêng biệt, chúng ta kết hợp chúng bằng dấu|
. Điều này có nghĩa: nếuuser
là “admin” hoặc “manager”, hàm sẽ trả về chuỗi “Full access” (Toàn quyền truy cập).case "Guest": return "Limited access":
Nếuuser
là “Guest”, hàm sẽ trả về “Limited access” (Quyền truy cập hạn chế).case _: return "No access":
Tương tự như ví dụ trước,case _
sẽ được thực hiện nếu không có trường hợp nào ở trên khớp vớiuser
, trả về “No access” (Không có quyền truy cập).- p
rint(access("manager"))
,print(access("Guest"))
,print(access("Ravi"))
: Gọi hàmaccess
với các tên người dùng khác nhau để minh họa kết quả.
Sử dụng danh sách (List) làm đối số trong câu lệnh match-case
Vì Python có thể so khớp biểu thức với bất kỳ giá trị nào (literal), bạn có thể dùng một danh sách làm giá trị của case
. Hơn nữa, đối với danh sách có số lượng phần tử thay đổi, bạn có thể sử dụng toán tử *
để phân tách các phần tử thành một chuỗi.
Trong đoạn code dưới đây, chúng ta sẽ sử dụng danh sách làm đối số trong câu lệnh match case.
def greeting(details):
match details:
case [time, name]:
return f'Good {time} {name}!'
case [time, *names]:
msg=''
for name in names:
msg+=f'Good {time} {name}!\n'
return msg
print (greeting(["Morning", "Ravi"]))
print (greeting(["Afternoon","Guest"]))
print (greeting(["Evening", "Kajal", "Praveen", "Lata"]))
Khi chạy đoạn code trên, kết quả sẽ là:
Good Morning Ravi!
Good Afternoon Guest!
Good Evening Kajal!
Good Evening Praveen!
Good Evening Lata!
Giải thích chi tiết:
def greeting(details):
: Định nghĩa hàmgreeting
nhận một tham sốdetails
(chính là danh sách).match details:
: Bắt đầu câu lệnhmatch
để so sánh giá trị của danh sáchdetails
.case [time, name]: return f'Good {time} {name}!'
: Nếu danh sáchdetails
có đúng 2 phần tử, chúng sẽ được gán chotime
vàname
, và hàm sẽ trả về lời chào theo định dạng “Good {time} {name}!”.case [time, *names]: ...
: Đây là phần thú vị nhất. Nếu danh sáchdetails
có ít nhất 1 phần tử, phần tử đầu tiên sẽ được gán chotime
. Các phần tử còn lại (nếu có) sẽ được gom lại thành một danh sáchnames
nhờ toán tử*
. Tiếp theo, hàm sẽ lặp qua cácname
trongnames
và tạo ra chuỗi lời chào tương ứng. Cuối cùng hàm sẽ trả về chuỗi lời chào.print(greeting(["Morning", "Ravi"]))
,print(greeting(["Afternoon", "Guest"]))
,print(greeting(["Evening", "Kajal", "Praveen", "Lata"]))
: Gọi hàmgreeting
với các danh sách đầu vào khác nhau để thấy rõ sự linh hoạt củamatch-case
với danh sách.
Sử dụng if trong mệnh đề Case
Thông thường, Python sẽ so khớp một biểu thức với các giá trị cố định (literal) trong các case. Tuy nhiên, bạn cũng có thể thêm một mệnh đề if vào trong case để tính toán điều kiện so khớp của biến. Điều này giúp bạn có thể kiểm tra điều kiện một cách linh hoạt hơn khi muốn lựa chọn trường hợp phù hợp.
Trong ví dụ dưới đây, hàm nhận vào một danh sách chứa số tiền và thời hạn, và mục đích là tính lãi suất cho số tiền ít hơn hoặc lớn hơn 10000. Điều kiện này sẽ được đưa vào ngay trong mệnh đề case.
def intr(details):
match details:
case [amt, duration] if amt<10000:
return amt*10*duration/100
case [amt, duration] if amt>=10000:
return amt*15*duration/100
print ("Interest = ", intr([5000,5]))
print ("Interest = ", intr([15000,3]))
Khi chạy đoạn code trên, kết quả sẽ là:
Interest = 2500.0
Interest = 6750.0
Giải thích chi tiết:
def intr(details):
: Định nghĩa hàmintr
nhận một danh sáchdetails
(chứa số tiền và thời hạn).match details:
: Bắt đầu câu lệnhmatch
để so sánhdetails
.case [amt, duration] if amt < 10000:
: Đây là phần quan trọng. Câu lệnh này nói rằng: Nếudetails
là một danh sách có 2 phần tử, và giá trị của phần tử đầu tiên (gán cho biếnamt
) nhỏ hơn 10000, thì hàm sẽ tính toán lãi suất theo công thứcamt * 10 * duration / 100
và trả về kết quả.case [amt, duration] if amt >= 10000:
: Tương tự, nếudetails
là một danh sách có 2 phần tử, và giá trị của phần tử đầu tiên (gán cho biếnamt
) lớn hơn hoặc bằng 10000, thì lãi suất sẽ được tính theo công thức khácamt * 15 * duration / 100
.print("Interest = ", intr([5000, 5])) và print("Interest = ", intr([15000, 3]))
: Gọi hàmintr
với hai bộ dữ liệu khác nhau để kiểm tra kết quả.
Lời kết
Vậy là chúng ta đã cùng nhau khám phá chi tiết về cú pháp và cách sử dụng match-case trong Python. Hy vọng qua bài viết này, bạn đã nắm vững cách áp dụng câu lệnh này vào thực tế để code Python một cách hiệu quả và dễ đọc hơn.