- Lệnh switch truyền thống không tồn tại trong Python, nhưng nó có thể được mô phỏng hiệu quả bằng các điều kiện và từ điển.
- Bắt đầu từ Python 3.10, cấu trúc match-case mới mang lại sức mạnh và khả năng đọc tốt hơn bằng cách thay thế cấu trúc switch-case cổ điển.
- Nhiều kỹ thuật khác nhau cho phép bạn triển khai logic trắc nghiệm trong Python, phù hợp với nhiều tình huống và phiên bản ngôn ngữ khác nhau.

Bạn đã bao giờ tự hỏi làm thế nào để xử lý nhiều điều kiện trong Python một cách dễ dàng và hiệu quả chưa? Khi bạn đã làm việc với các ngôn ngữ như C, Java hoặc JavaScript, chắc chắn bạn đã sử dụng trường hợp chuyển mạch để lựa chọn giữa một số tùy chọn dựa trên giá trị của một biến. Tuy nhiên, trong Python, cơ chế cổ điển này không tồn tại... cho đến gần đây. Tất nhiên, trong khi các nhà phát triển đã phải tìm kiếm các giải pháp thay thế trong nhiều năm, ngôn ngữ này hiện cung cấp một giải pháp hiện đại và mạnh mẽ.
Bài viết này là hướng dẫn cơ bản giúp bạn hiểu cách sử dụng lệnh switch tương đương trong Python., khám phá các giải pháp thay thế mạnh mẽ nhất trong các phiên bản cũ hơn, làm rõ lý do tại sao nó không được tích hợp trong giai đoạn đầu và tìm hiểu cách viết mã sạch hơn, dễ đọc hơn, bất kể bạn đang sử dụng phiên bản nào. Hãy sẵn sàng tìm hiểu tất cả các thủ thuật, ví dụ và sự khác biệt chính trong việc triển khai nhiều điều kiện trong hệ sinh thái Python.
Switch có tồn tại trong Python không? Lịch sử và lý do tại sao nó không tồn tại
Lệnh switch-case có trong nhiều ngôn ngữ, nhưng chưa chính thức xuất hiện trong Python cho đến phiên bản 3.10. Lý do chính là triết lý: những người sáng tạo ra Python luôn cam kết về tính đơn giản và dễ đọc. Họ tin rằng việc giới thiệu cú pháp chuyển đổi mới có thể làm phức tạp mọi thứ, vì vậy if-elif-else đủ để lấp đầy khoảng trống đó. Hơn nữa, chưa bao giờ có sự đồng thuận về cú pháp lý tưởng. Trên thực tế, một số đề xuất chính thức (PEP 275, PEP 3103) đã bị từ chối do thiếu sự đồng thuận và vì nhiều người tin rằng các giải pháp thay thế hiện có đủ rõ ràng và mạnh mẽ.
Trong nhiều năm, cộng đồng đã bù đắp cho việc không có công tắc bằng cách sử dụng chuỗi điều kiện và từ điển. Không cần phải nói, chủ đề này đã tạo ra cuộc tranh luận, nhưng không phải là một bất lợi không thể khắc phục, những cách tiếp cận này đã chứng minh được tính linh hoạt và khả năng thích ứng cao. Tuy nhiên, khi các dự án ngày càng phức tạp, nhu cầu về một giải pháp thanh lịch hơn ngày càng tăng.
Vỏ công tắc là gì và nó được sử dụng để làm gì?
El trường hợp chuyển mạch Đây là một cấu trúc điều khiển được sử dụng trong nhiều ngôn ngữ để thực thi các khối mã khác nhau dựa trên giá trị của một biến hoặc biểu thức. Nói cách khác, nó cho phép bạn chọn một tùy chọn từ nhiều tùy chọn có thể theo cách rõ ràng và trực tiếp, tránh các chuỗi điều kiện vô tận.
Các ví dụ sử dụng điển hình sẽ là: hiển thị tên của một ngày trong tuần dựa trên một con số, chỉ định điểm, chọn các hoạt động dựa trên đầu vào của người dùng, v.v. Trong các ngôn ngữ như C hoặc Java, cú pháp của nó rất đơn giản:
switch(valor) {
case 1:
// acción
break;
case 2:
// otra acción
break;
default:
// acción por defecto
}
Trong Python, cấu trúc cổ điển này mới xuất hiện gần đây, do đó các nhà phát triển phải sáng tạo để đạt được kết quả tương tự.
Sự xuất hiện của lệnh switch trong Python: câu lệnh match-case (kể từ Python 3.10)
Với việc phát hành phiên bản 3.10, Python đã tích hợp một tính năng được mong đợi từ lâu: câu lệnh so khớp trường hợp. Mặc dù cú pháp của nó gợi nhớ đến switch-case truyền thống, nhưng thực tế nó mạnh hơn nhiều vì nó giới thiệu khớp mẫu (so khớp mẫu), cho phép so sánh không chỉ các giá trị đơn giản mà còn cả các cấu trúc phức tạp, bộ, lớp, danh sách, từ điển, v.v.
Match-case của Python được viết như thế này:
def ejemplo_switch(x):
match x:
case 1:
return "uno"
case 2:
return "dos"
case _:
return "desconocido"
Dấu gạch dưới (_) hoạt động như một ký tự đại diện và tương đương với mặc định Trong các ngôn ngữ khác, thực thi khi không có mẫu nào trước đó khớp.
Tại sao nó lại mạnh mẽ như vậy? Bởi vì bạn có thể nhận được các mẫu phức tạp, nắm bắt các biến, mở các bộ hoặc đối tượng và thậm chí sử dụng các bảo vệ để thêm các điều kiện bổ sung sau trường hợp:
match dato:
case (a, b) if a > b:
print("El primer elemento es mayor que el segundo")
case (a, b):
print(f"Valores: {a}, {b}")
Ngoài ra, trong Python 3.10 trở lên, cấu trúc này cải thiện khả năng đọc, khả năng bảo trì và khả năng mở rộng của mã, đặc biệt là khi xử lý nhiều trường hợp.
Các lựa chọn thay thế để chuyển đổi trong Python cho các phiên bản cũ hơn
Trước khi xuất hiện trường hợp phù hợp, các nhà phát triển đưa ra những giải pháp thay thế có giá trị tương đương. Hai cách phổ biến nhất là sử dụng chuỗi if-elif-else và lập bản đồ bằng từ điểnChúng ta hãy xem xét kỹ hơn:
1. Sử dụng if-elif-else
Giải pháp trực tiếp và dễ hiểu nhất là nối các điều kiện bằng if, elif và else. Bằng cách này, bạn có thể bao phủ tất cả các giá trị có thể có cho một biến và thực thi khối mã tương ứng. Ví dụ, để hiển thị ngày trong tuần dựa trên một số:
dia = 4
if dia == 1:
print('lunes')
elif dia == 2:
print('martes')
elif dia == 3:
print('miércoles')
elif dia == 4:
print('jueves')
elif dia == 5:
print('viernes')
elif dia == 6:
print('sábado')
elif dia == 7:
print('domingo')
else:
print('error')
Ưu điểm của cách tiếp cận này:
- Mã đơn giản và dễ đọc.
- Bạn không cần bất kỳ cấu trúc đặc biệt nào khác; đây là Python thuần túy.
- Có thể sử dụng bất kỳ loại so sánh nào, không chỉ có so sánh bằng.
Nhược điểm của thang if-elif-else:
- Có xu hướng lặp lại mã. Bạn phải lặp lại biến trong mỗi lần so sánh, điều này tạo ra rất nhiều văn bản không cần thiết nếu bạn có nhiều trường hợp.
- Ít hiệu quả hơn khi có nhiều điều kiện. Nếu vụ án đã ở giai đoạn cuối, tất cả các vụ án trước đó sẽ được đánh giá trước khi đến.
- Khó khăn khi thêm hoặc xóa các trường hợp một cách linh hoạt.
2. Sử dụng từ điển để mô phỏng trường hợp chuyển đổi
Một cách rất Python để mô phỏng các công tắc là sử dụng từ điển. Ý tưởng rất đơn giản: bạn liên kết mỗi giá trị có thể (khóa) với hàm hoặc hành động tương ứng (giá trị). Sau đó, bạn tra cứu từ điển để lấy hàm và thực thi nó:
def lunes():
print('lunes')
def martes():
print('martes')
def error():
print('error')
switch_semana = {
1: lunes,
2: martes,
# ... otros días ...
}
dia = 8
switch_semana.get(dia, error)()
Ưu điểm của phương pháp này:
- Mã lệnh nhỏ gọn và dễ mở rộng.
- Truy cập vào chức năng phù hợp rất nhanh. Từ điển sử dụng hàm băm, do đó việc tìm kiếm diễn ra gần như ngay lập tức.
- Cho phép bạn gán cùng một chức năng cho nhiều phím (ví dụ: cho các trường hợp nhóm).
- Công tắc có thể được sửa đổi khi chạy.
Nhược điểm:
- Yêu cầu phải xác định trước tất cả các chức năng liên quan, điều này có thể gây phức tạp cho các hành động đơn giản.
- Nó chỉ cho phép so sánh để tìm sự bằng nhau (không áp dụng cho khoảng, phạm vi, v.v.).
- Nó không dành cho những trường hợp có logic điều kiện phức tạp hơn trong mỗi lựa chọn.
Sự khác biệt giữa if-elif-else và switch (hoặc match-case)
Cơ chế hoạt động bên trong của chuỗi if-elif-else khác với chuỗi switch. Trong if-elif-else, các điều kiện được đánh giá từng cái một, từ trên xuống dưới, cho đến khi điều kiện đầu tiên là đúng. Do đó, nếu giá trị được tìm kiếm ở đầu, nó sẽ thực thi nhanh; nếu ở cuối, nó sẽ mất nhiều thời gian hơn.
Thay vào đó, các công tắc truyền thống (và từ điển là giải pháp thay thế trong Python) thường sử dụng bảng tra cứu, do đó việc truy cập đồng đều hơn, bất kể có bao nhiêu trường hợp hoặc vị trí của chúng. trường hợp phù hợp và từ điển, thời gian truy cập đồng đều hơn nhiều.
Khi nào nên chọn phương án thay thế?
Không có giải pháp chung duy nhất; công cụ tốt nhất phụ thuộc vào vấn đề cụ thể.
- Đối với số lượng điều kiện nhỏ hoặc logic phức tạp trong mỗi nhánh, if-elif-else là lựa chọn đơn giản nhất. Nó cho phép so sánh và rất linh hoạt.
- Khi bạn có nhiều trường hợp và mỗi trường hợp chỉ thực hiện một hành động cụ thể, hãy dựa vào từ điển. Mã sạch hơn, có khả năng mở rộng và dễ bảo trì hơn.
- Nếu bạn sử dụng Python 3.10 hoặc cao hơn, trường hợp phù hợp Đây là lựa chọn tốt nhất về độ rõ nét và sức mạnh. Nó cho phép bạn kết hợp sự thanh lịch của công tắc với sức mạnh của việc khớp mẫu trên các cấu trúc phức tạp.
Luôn nghĩ về khả năng đọc, hiệu suất và khả năng bảo trì của mã của bạn.
Ví dụ thực tế về việc sử dụng switch trong Python và các giải pháp thay thế
Hãy cùng xem xét một số ví dụ trong đó mỗi giải pháp thay thế này được áp dụng, từ mức độ phức tạp ít nhất đến cao nhất:
Ví dụ 1: Tính điểm dựa trên điểm số
# Usando if-elif-else
puntuacion = 85
if puntuacion >= 90:
print('Sobresaliente')
elif puntuacion >= 80:
print('Notable')
elif puntuacion >= 70:
print('Bien')
else:
print('Insuficiente')
Trường hợp này hoàn hảo để sử dụng câu điều kiện, vì bạn đang làm việc với khoảng thời gian chứ không phải giá trị cố định.
Ví dụ 2: Hiển thị ngày trong tuần theo số (có từ điển)
# Definición de funciones para cada día
def lunes():
print('lunes')
def martes():
print('martes')
def miercoles():
print('miércoles')
def jueves():
print('jueves')
def viernes():
print('viernes')
def sabado():
print('sábado')
def domingo():
print('domingo')
def error():
print('error')
switch_semana = {
1: lunes,
2: martes,
3: miercoles,
4: jueves,
5: viernes,
6: sabado,
7: domingo
}
dia = 8
switch_semana.get(dia, error)()
Ví dụ 3: Sử dụng match-case để chọn phép toán số học
operacion = 'suma'
a = 10
b = 5
match operacion:
case 'suma':
print(a + b)
case 'resta':
print(a - b)
case 'multiplicacion':
print(a * b)
case 'division':
print(a / b)
case _:
print('Operación no válida')
Như bạn thấy, cú pháp rất đơn giản và rõ ràng. Dấu gạch dưới chỉ ra trường hợp mặc định.
Ví dụ nâng cao: khớp mẫu với match-case
Điểm mạnh lớn nhất của match-case là khả năng xử lý các mẫu phức tạp. Ví dụ, bạn có thể phân tích cú pháp các bộ, danh sách, từ điển, đối tượng, v.v.
punto = (3, 5)
match punto:
case (0, 0):
print('Origen')
case (0, y):
print(f'Eje Y en {y}')
case (x, 0):
print(f'Eje X en {x}')
case (x, y):
print(f'Coordenadas X={x}, Y={y}')
Bạn thậm chí có thể sử dụng mệnh đề if (bảo vệ) để thêm các điều kiện bổ sung vào mỗi trường hợp.
Sự khác biệt về hiệu suất giữa if-elif-else, từ điển và match-case
Trong hầu hết các trường hợp, sự khác biệt về hiệu suất là không đáng kể đối với các tập lệnh thông thường. Tuy nhiên, khi có nhiều lựa chọn thay thế, từ điển và match-case có thể hiệu quả hơn vì chúng làm giảm số lượng so sánh. Tuy nhiên, yếu tố quan trọng nhất thường là khả năng đọc và bảo trì mã, thay vì những tối ưu hóa nhỏ hiếm khi tạo ra sự khác biệt trong các dự án thực tế.
Sử dụng kỹ thuật giúp mã rõ ràng hơn và tránh lỗi.
Giải pháp sáng tạo: các lớp và trình quản lý ngữ cảnh để mô phỏng chuyển đổi
Một số nhà phát triển đã tạo ra các lớp chuyên biệt cho phép mô phỏng hành vi chuyển đổi cổ điển, bao gồm các tùy chọn nâng cao như thêm phá vỡ để kiểm soát việc thực hiện các trường hợp tiếp theo, nhóm các trường hợp, tùy chỉnh so sánh hoặc kích hoạt chế độ nghiêm ngặt để đảm bảo chỉ có một nhánh được thực hiện.
Ví dụ, một trình quản lý ngữ cảnh tùy chỉnh có thể được triển khai để sử dụng cú pháp rất giống với các ngôn ngữ khác:
class switch:
def __init__(self, variable, comparator=None, strict=False):
self.variable = variable
self.matched = False
self.matching = False
if comparator:
self.comparator = comparator
else:
self.comparator = lambda x, y: x == y
self.strict = strict
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def case(self, expr, break_=False):
if self.strict:
if self.matched:
return False
if self.matching or self.comparator(self.variable, expr):
if not break_:
self.matching = True
else:
self.matched = True
self.matching = False
return True
else:
return False
else:
if self.matching or self.comparator(self.variable, expr):
if not break_:
self.matching = True
else:
self.matched = True
self.matching = False
return True
else:
return False
def default(self):
return not self.matched and not self.matching
Sử dụng lớp này cho phép sử dụng cú pháp như sau:
dia = 4
with switch(dia) as s:
if s.case(1, True): print('lunes')
if s.case(2, True): print('martes')
if s.case(3, True): print('miércoles')
if s.case(4, True): print('jueves')
if s.case(5, True): print('viernes')
if s.case(6, True): print('sábado')
if s.case(7, True): print('domingo')
if s.default(): print('error')
Ưu điểm của giải pháp này là gì? Nó có cú pháp rất quen thuộc đối với những người đến từ ngôn ngữ khác và cho phép tùy chỉnh nâng cao, chẳng hạn như sử dụng bất kỳ hàm so sánh nào, nhóm các trường hợp, chạy nhiều nhánh hoặc chỉ một nhánh, v.v. Nhược điểm là nó thường chậm hơn và yêu cầu nhập hoặc xác định lớp đặc biệt.
Sử dụng hàm lambda để đơn giản hóa các hành động trên từ điển
Nhiều khi bạn không cần phải xác định các hàm riêng biệt cho từng hành động; bạn có thể sử dụng các hàm ẩn danh (lambda). Điều này đặc biệt thực tế khi hành động cần thực hiện rất đơn giản:
switch_operaciones = {
'sumar': lambda a, b: a + b,
'restar': lambda a, b: a - b,
'multiplicar': lambda a, b: a * b
}
operacion = 'sumar'
resultado = switch_operaciones.get(operacion, lambda a, b: None)(5, 3)
print(resultado)
Điều này làm cho mã trở nên gọn nhẹ và dễ mở rộng mà không làm mất đi tính rõ ràng.
Các trường hợp sử dụng nâng cao: So khớp mẫu trong Match-Case
Kết án trường hợp phù hợp Python 3.10 vượt xa việc sao chép switch-case cổ điển. Sức mạnh thực sự của nó nằm ở khớp mẫu cấu trúcVí dụ, nó cho phép bạn phân biệt giữa các cấu trúc dữ liệu khác nhau, các lớp tùy chỉnh, phân tích đối tượng và nắm bắt các phần tử phụ một cách dễ dàng.
Ví dụ với danh sách và bộ:
datos =
match datos:
case :
print('Lista con 1, 2, 3')
case :
print('Lista que empieza con 1')
case _:
print('Otra lista')
Ví dụ với các đối tượng (giả sử là lớp Point):
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
p = Punto(2, 3)
match p:
case Punto(x=0, y=0):
print('Origen')
case Punto(x, y):
print(f'Coordenadas: {x} {y}')
Cơ chế này cho phép bạn viết mã có khả năng biểu đạt cao, thích ứng với các cấu trúc phức tạp mà không làm mất đi khả năng đọc.
Các khía cạnh cần xem xét khi di chuyển mã: khả năng tương thích và các biện pháp thực hành tốt nhất
Không phải tất cả các dự án đều có thể sử dụng match-case ngay lập tức. Nếu bạn đang làm việc trong môi trường có phiên bản Python cũ hơn (ví dụ: 3.8 hoặc 3.9), bạn sẽ cần phải chọn từ điển. Khi bạn có thể nâng cấp lên 3.10 hoặc mới hơn, hãy tận dụng sức mạnh và tính rõ ràng của việc khớp mẫu, đặc biệt là trong các dự án mà logic lựa chọn nhiều là cần thiết.
Ghi nhớ:
- Chọn tùy chọn cung cấp khả năng đọc, tính linh hoạt và dễ bảo trì tốt nhất.
- Trong những bài toán rất đơn giản (một vài trường hợp), if-elif-else thường đủ và trực tiếp hơn.
- Đối với các bảng lựa chọn lớn, hãy sử dụng từ điển và hàm.
- Đối với các cấu trúc phức tạp hoặc để tận dụng tối đa Python hiện đại, hãy chọn match-case.
Một mẹo nhỏ: bạn có thể chuyển đổi các hàm hiện có để chấp nhận từ điển hành động, giúp việc chuyển đổi giữa các phương pháp trở nên dễ dàng hơn.
Mẹo tối ưu hóa và thiết kế để có mã Python sạch hơn
Đừng mắc sai lầm khi thiết kế chuỗi điều kiện vô tận chỉ để bắt chước lệnh chuyển đổi cổ điển. Hãy suy nghĩ về từng trường hợp cụ thể và đánh giá cấu trúc điều khiển nào mang lại giá trị nhất cho ngữ cảnh chương trình của bạn. Hãy nhớ rằng Python coi trọng sự rõ ràng, vì vậy hãy tránh làm phức tạp quá mức mã của bạn nếu bạn có thể đạt được cùng một kết quả dễ dàng hơn.
Một mẹo quan trọng: Khi sử dụng từ điển, hãy sử dụng chức năng get() để tránh lỗi nếu khóa không tồn tại và do đó có thể xác định trường hợp mặc định một cách khéo léo.
So sánh với các ngôn ngữ khác và suy nghĩ cuối cùng
Trong một số ngôn ngữ, chẳng hạn như C, C++ hoặc Java, các lệnh chuyển đổi chỉ cho phép so sánh các giá trị đơn giản (số nguyên, chuỗi) và cung cấp ít giá trị cho các cấu trúc phức tạp. Python tiến xa hơn một bước: đầu tiên, nó cung cấp các giải pháp thay thế đa năng (if-elif-else, từ điển) và giờ đây nó mở ra cánh cửa cho logic nâng cao mà không cần nỗ lực thêm. Điều quan trọng là tận dụng lợi thế của từng phiên bản và không ép buộc bản thân bắt chước các cú pháp khác nếu vấn đề đòi hỏi một giải pháp khác.
Nếu bạn mới bắt đầu với Python hoặc đến từ ngôn ngữ khác, đừng nản lòng nếu bạn không tìm thấy từ khóa switch trong hướng dẫn. Hãy nghĩ về tất cả các khả năng có sẵn và chọn khả năng phù hợp nhất với ngữ cảnh và nhu cầu của bạn.
Quản lý nhiều phương án thay thế trong Python chưa bao giờ dễ dàng hoặc mạnh mẽ hơn thế. Bây giờ bạn đã hiểu lý do đằng sau sự vắng mặt (và sự xuất hiện sau đó) của switch, cách mô phỏng nó hiệu quả trong bất kỳ phiên bản nào và cách tận dụng tối đa câu lệnh match-case mới. Cho dù bạn phải lựa chọn giữa nửa tá tùy chọn, thao tác các cấu trúc phức tạp, tuân theo các phương pháp hay nhất hay lo lắng về hiệu suất, bạn đều có các phương án thay thế mạnh mẽ, thanh lịch và linh hoạt. Cho dù mã của bạn dành cho các tập lệnh nhanh hay các ứng dụng phức tạp, Python đều cung cấp cho bạn các công cụ để viết mã rõ ràng, nhanh chóng và dễ dàng.
Mục lục
- Switch có tồn tại trong Python không? Lịch sử và lý do tại sao nó không tồn tại
- Vỏ công tắc là gì và nó được sử dụng để làm gì?
- Sự xuất hiện của lệnh switch trong Python: câu lệnh match-case (kể từ Python 3.10)
- Các lựa chọn thay thế để chuyển đổi trong Python cho các phiên bản cũ hơn
- Sự khác biệt giữa if-elif-else và switch (hoặc match-case)
- Khi nào nên chọn phương án thay thế?
- Ví dụ thực tế về việc sử dụng switch trong Python và các giải pháp thay thế
- Ví dụ nâng cao: khớp mẫu với match-case
- Sự khác biệt về hiệu suất giữa if-elif-else, từ điển và match-case
- Giải pháp sáng tạo: các lớp và trình quản lý ngữ cảnh để mô phỏng chuyển đổi
- Sử dụng hàm lambda để đơn giản hóa các hành động trên từ điển
- Các trường hợp sử dụng nâng cao: So khớp mẫu trong Match-Case
- Các khía cạnh cần xem xét khi di chuyển mã: khả năng tương thích và các biện pháp thực hành tốt nhất
- Mẹo tối ưu hóa và thiết kế để có mã Python sạch hơn
- So sánh với các ngôn ngữ khác và suy nghĩ cuối cùng