Как реализовать множественное ветвление условий без `elif`?

Множественное ветвление без elif можно реализовать несколькими способами:

  1. Использование словаря (dispatch table): Определить словарь, где ключи - условия, а значения - функции, которые нужно выполнить. Затем, основываясь на условии, выбирать и вызывать нужную функцию.
  2. Вложенные if блоки: Хотя это и не рекомендуется для сложной логики, можно использовать вложенные if, но это ухудшает читаемость.
  3. Использование match (Python 3.10+): Оператор match позволяет сравнивать переменную с несколькими паттернами и выполнять соответствующий блок кода.

Пример (словарь):


def func_a(): print("A")
def func_b(): print("B")
def func_c(): print("C")

switcher = {
    "a": func_a,
    "b": func_b,
    "c": func_c
}

choice = "b"
switcher.get(choice, lambda: print("Default"))() # Выведет "B"
  

Множественное ветвление условий без `elif` в Python можно реализовать несколькими способами:

  • Использование словаря (словарь соответствий, dispatch table): Это, пожалуй, самый распространенный и элегантный способ. Ключами словаря являются условия (или значения, соответствующие условиям), а значениями - функции (или lambda-выражения), которые нужно выполнить при выполнении соответствующего условия.
    
            def case_1():
              return "Выполнено условие 1"
    
            def case_2():
              return "Выполнено условие 2"
    
            def default_case():
              return "Условие не выполнено"
    
            def switch(argument):
              switcher = {
                  1: case_1,
                  2: case_2
              }
              func = switcher.get(argument, default_case) # get возвращает default_case если argument не найден
              return func()
    
            print(switch(1))  # Вывод: Выполнено условие 1
            print(switch(2))  # Вывод: Выполнено условие 2
            print(switch(3))  # Вывод: Условие не выполнено
          
    Преимущества: Читаемость, расширяемость, возможность легко добавлять новые условия. Функции могут быть сложными.
  • Цепочка `if` с оператором `return` (или `continue`): Этот подход может быть полезен, если каждая ветка кода завершается `return` (или `continue` в цикле). Тогда `elif` не нужен, т.к. после выполнения `return` (или `continue`) последующие `if` не будут проверяться.
    
            def process_value(value):
              if value == 1:
                return "Обработка значения 1"
              if value == 2:
                return "Обработка значения 2"
              if value > 5:
                return "Обработка значения больше 5"
              return "Обработка значения по умолчанию"
    
            print(process_value(1))  # Вывод: Обработка значения 1
            print(process_value(2))  # Вывод: Обработка значения 2
            print(process_value(7))  # Вывод: Обработка значения больше 5
            print(process_value(0))  # Вывод: Обработка значения по умолчанию
          
    Преимущества: Простота для небольшого количества условий. Недостатки: Плохо масштабируется, если логика в каждой ветке сложная и не всегда завершается `return`.
  • Использование списков или кортежей с лямбда-функциями (менее читабельный): Можно создать список кортежей, где первый элемент кортежа - условие, а второй - лямбда-функция. Затем перебрать список и выполнить первую лямбда-функцию, условие которой истинно. Это решение считается менее читабельным, чем использование словаря.
    
            conditions = [
                (lambda x: x == 1, lambda: "Условие 1"),
                (lambda x: x == 2, lambda: "Условие 2"),
                (lambda x: x > 5, lambda: "Условие больше 5"),
                (lambda x: True, lambda: "Условие по умолчанию") # Всегда True - как else
            ]
    
            def check_conditions(value):
              for condition, action in conditions:
                if condition(value):
                  return action()
    
            print(check_conditions(1)) # Вывод: Условие 1
            print(check_conditions(2)) # Вывод: Условие 2
            print(check_conditions(7)) # Вывод: Условие больше 5
            print(check_conditions(0)) # Вывод: Условие по умолчанию
          
    Преимущества: Можно записать в одну строку, если сильно нужно (не рекомендуется). Недостатки: Плохая читаемость, сложность отладки.

Рекомендации:

  • Для большинства случаев лучшим выбором является использование словаря (словарь соответствий).
  • Цепочка `if` с `return` подходит для простых случаев, когда условия независимы друг от друга и каждая ветка завершается `return`.
  • Использование списков/кортежей с лямбда-функциями следует избегать из-за низкой читаемости.

При выборе способа реализации множественного ветвления важно учитывать читаемость, расширяемость и сложность логики в каждой ветке.

0