Case function in python

Есть ли в Python оператор switch case?

Столкнулся с тем, что требуется реализовать множественное условие, которое в других языках я бы реализовал с помощью конструкции switch-case . В Python мне приходится расписывать всё через условия if-elif-else . Это мне кажется довольно неудобным. Есть ли более удобный способ записи подобных условий? Например, у меня есть единицы измерения и в зависимости от выбранной мне нужно вернуть соответствующий множитель:

def get_multiplier(unit): if unit == 'mm': return 10**-3 if unit == 'cm': return 10**-2 if unit == 'dm': return 10**-1 if unit == 'm': return 1 if unit == 'km': return 10**3 raise ValueError('Undefined unit: <>'.format(unit)) 

В Ноябре 2019ого Гуидо сказал что после его нынешнего проекта pegen (PEG parser generator) он хочет добавить match statement. Может быть он появится в Python 3.10 или 3.11?

5 ответов 5

UPD (16.02.2022)

Обновление добавлено по причине появления конструкции match-case в python 3.10 . Ответ, который дополняет в этой ветке и расширенный ответ в связи с изменениями.

Ответ ниже продолжает быть актуальным, как в версиях ниже 3.10 , так и в версии 3.10

Для начала, ничего особенно плохого в использовании конструкции if-elif-else нет.

При желании можно найти несколько альтернатив.

Использование словарей

Довольно распространённый способ организации конструкции switch-case в Python — это использование словаря. Проще показать на примере:

Для того, чтобы получить нужный множитель в этом случае требуется лишь взять значение по ключу:

try: mult = unit_to_multiplier['cm'] except KeyError as e: # можно также присвоить значение по умолчанию вместо бросания исключения raise ValueError('Undefined unit: <>'.format(e.args[0])) 

Если вы твёрдо уверены, что значение всегда будет присутствовать в словаре, можете опустить блок try-except и быть готовым ловить исключение в другом месте.

Некоторой вариацией этого подходя будет предварительная проверка значения в условии:

if unit in unit_to_multiplier: mult = unit_to_multiplier[unit] else: # обработка отсутствия значения в словаре 

В Python принято использовать подход, звучащий примерно так: «лучше попробовать и получить ошибку, чем каждый раз спрашивать разрешение», поэтому более предпочтительный подход с использованием исключений.

Если хочется использовать значение по умолчанию в случае, если ключ отсутствует, удобно использовать метод get :

mult = unit_to_multiplier.get('ultra-meter', 0) 

Если словарь вам требуется один раз, можно объединить эти выражения в одно:

unit_to_multiplier = < 'mm': 10**-3, 'cm': 10**-2, 'dm': 10**-1, 'm': 1, 'km': 10**3 >.get('km', 0) 

На этом возможности этого подхода не заканчиваются. Можно использовать условные выражения в качестве ключей словаря:

def get_temp_description(temp): return < temp < -20: 'Холодно', -20 [True] 

Этот словарь после вычисления будет иметь два ключа True и False . Нас интересует ключ True . Будьте внимательны, что условия не перекрываются!

Читайте также:  Php mysql from novice

Подобные словари могут проверять произвольное свойство, например, тип (источник примера):

selector = < type(x) == str : "it's a str", type(x) == tuple: "it's a tuple", type(x) == dict : "it's a dict" >[1] # можно использовать число 1 как синоним True 

При необходимости более сложных действий хранить функцию в качестве значения по каждому ключу:

import operator operations = < '+': operator.add, '*': lambda x, y: x * y, # . >def calc(operation, a, b): return operations[operation](a, b) 

Будьте внимательны при использовании словаря с функциями — убедитесь, что вы не вызываете эти функции внутри словаря, а передаёте по ключу; иначе все функции будут выполняться каждый раз при конструировании словаря.

Другие способы

Приведены скорее для ознакомления, чем для реального использования.

 def process_first(self): . def process_second(self): . . 
 def dispatch(self, value): method_name = 'process_' + str(value) method = getattr(self, method_name) return method() 
 class switch(object): def __init__(self, value): self.value = value # значение, которое будем искать self.fall = False # для пустых case блоков def __iter__(self): # для использования в цикле for """ Возвращает один раз метод match и завершается """ yield self.match raise StopIteration def match(self, *args): """ Указывает, нужно ли заходить в тестовый вариант """ if self.fall or not args: # пустой список аргументов означает последний блок case # fall означает, что ранее сработало условие и нужно заходить # в каждый case до первого break return True elif self.value in args: self.fall = True return True return False 
 x = int(input()) for case in switch(x): if case(1): pass if case(2): pass if case(3): print('Число от 1 до 3') break if case(4): print('Число 4') if case(): # default print('Другое число') 
 # Условная конструкция Select Case x Case x 

Этот способ использует короткую схему вычисления операторов and и or , т.е. то, что логические выражения вычисляются следующим образом: ( t вычисляющееся как True , f вычисляется как False ):

 f and x = f t and x = x f or x = x t or x = t 

Предложенный способ вычислений будет работать только в том случае, если второй аргумент оператора and всегда будет содержать True -выражение, иначе этот блок всегда будет пропускаться. Например:

 import sys class case_selector(Exception): def __init__(self, value): # один обязательный аргумент Exception.__init__(self, value) def switch(variable): raise case_selector(variable) def case(value): exc_сlass, exс_obj, _ = sys.exc_info() if exc_сlass is case_selector and exс_obj.args[0] == value: return exс_class return None 

Здесь используется функция sys.exc_info , которая возвращает набор из информации об обрабатываемом исключении: класса, экземпляра и стека. Код с использованием этих конструкций будет выглядеть следующим образом:

 n = int(input()) try: switch(n) except ( case(1), case(2), case(3) ): print "Число от 1 до 3" except case(4): print "Число 4" except: print "Другое число" 

Источник

Python Switch Statement – Switch Case Example

Kolade Chris

Kolade Chris

Python Switch Statement – Switch Case Example

Until version 3.10, Python never had a feature that implemented what the switch statement does in other programming languages.

So, if you wanted to execute multiple conditional statements, you would've had to use the elif keyword like this:

age = 120 if age > 90: print("You are too old to party, granny.") elif age < 0: print("You're yet to be born") elif age >= 18: print("You are allowed to party") else: "You're too young to party" # Output: You are too old to party, granny. 

From version 3.10 upwards, Python has implemented a switch case feature called “structural pattern matching”. You can implement this feature with the match and case keywords.

Some people debate whether or not the match and case are keywords in Python. This is because you can use both of them as variable and function names. But that’s another story for another day.

You can refer to both keywords as "soft keywords" if you like.

In this article, I will show you how to write a switch statement in Python using the match and case keywords.

But before that, I have to show you how Python programmers used to simulate a switch statement back in the day.

How Python Programmers Used to Simulate Switch Case

There were multiple ways Pythonistas simulated switch statements back in the day.

Using a function and the elif keyword was one of them and you can do it this way:

def switch(lang): if lang == "JavaScript": return "You can become a web developer." elif lang == "PHP": return "You can become a backend developer." elif lang == "Python": return "You can become a Data Scientist" elif lang == "Solidity": return "You can become a Blockchain developer." elif lang == "Java": return "You can become a mobile app developer" print(switch("JavaScript")) print(switch("PHP")) print(switch("Java")) """ Output: You can become a web developer. You can become a backend developer. You can become a mobile app developer """ 

How to Implement Switch Statements with the match and case Keywords in Python 3.10

To write switch statements with the structural pattern matching feature, you can use the syntax below:

match term: case pattern-1: action-1 case pattern-2: action-2 case pattern-3: action-3 case _: action-default 

Note that the underscore symbol is what you use to define a default case for the switch statement in Python.

An example of a switch statement written with the match case syntax is shown below. It is a program that prints what you can become when you learn various programming languages:

lang = input("What's the programming language you want to learn? ") match lang: case "JavaScript": print("You can become a web developer.") case "Python": print("You can become a Data Scientist") case "PHP": print("You can become a backend developer") case "Solidity": print("You can become a Blockchain developer") case "Java": print("You can become a mobile app developer") case _: print("The language doesn't matter, what matters is solving problems.") 

That’s a much cleaner syntax than multiple elif statements and simulating the switch statement with a function.

You probably noticed I did not add a break keyword to each of the cases, as it is done in other programming languages. That’s the advantage Python’s native switch statement has over those of other languages. The break keyword's functionality is done for you behind the scenes.

Conclusion

This article showed you how to write switch statements with the “match” and “case” keywords. You also learned how Python programmers used to write it before version 3.10.

The Python match and case statements were implemented to provide the functionality that the switch statement feature in other programming languages such as JavaScript, PHP, C++, and others give us.

Источник

What is the Python equivalent for a case/switch statement? [duplicate]

Python 3.10.0 provides an official syntactic equivalent, making the submitted answers not the optimal solutions anymore! In this SO post I try to cover everything you might want to know about the match - case construct, including common pitfalls if you're coming from other languages. Of course, if you're not using Python 3.10.0 yet, the existing answers apply and are still valid for 2021.

I would've written this in an answer to this post, but unfortunately it doesn't allow for any more answers. But with more than one million views, I think this question needs at least a redirection to a more modern answer - especially when 3.10.0 becomes stable and Python beginners come across this post.

2 Answers 2

Python 3.10 and above

In Python 3.10, they introduced the pattern matching.

def http_error(status): match status: case 400: return "Bad request" case 404: return "Not found" case 418: return "I'm a teapot" # If an exact match is not confirmed, this last case will be used if provided case _: return "Something's wrong with the internet" 

Before Python 3.10

While the official documentation are happy not to provide switch , I have seen a solution using dictionaries.

# define the function blocks def zero(): print "You typed zero.\n" def sqr(): print "n is a perfect square\n" def even(): print "n is an even number\n" def prime(): print "n is a prime number\n" # map the inputs to the function blocks options =

Then the equivalent switch block is invoked:

This begins to fall apart if you heavily depend on fall through.

Источник

Оцените статью