[Explained] Як реалізувати Switch-Case у Python

Бажаєте відтворити логіку перемикання варіантів у Python? Давайте розглянемо різноманітні способи, як можна досягти аналогічного ефекту.

Якщо ви мали досвід програмування на C або JavaScript, то, ймовірно, знайомі з конструкцією switch-case. Але яка її роль?

Уявімо ситуацію, коли є набір різних дій (чи фрагментів коду). І те, яку саме дію потрібно виконати, залежить від поточного значення змінної або результату виразу.

Ось кілька прикладів таких ситуацій:

  • Присвоєння оцінок студентам на основі набраних балів.
  • Вибір методу обробки рядків залежно від вибору користувача.
  • Виконання арифметичних операцій над двома числами на основі введених користувачем даних.

Отже, конструкція switch-case створює зручний спосіб для реалізації такої логіки. Коли вам потрібно виконати одну з багатьох дій, виходячи зі значення змінної або виразу.

Хоча Python не має вбудованої конструкції switch-case, існує декілька підходів, які дозволяють досягти подібної функціональності. У цій статті ми розглянемо ці підходи детально.

Імітація поведінки switch-case в Python

Подивимося на конкретному прикладі, як можна відтворити логіку switch-case у Python.

Створимо просту програму, яка виконує наступні дії:

  • Випадковим чином обирає слово з заданого списку слів.
  • Інформує користувача про контекст і пропонує варіанти операцій з рядками, які можна виконати над обраним словом.
  • Реалізує операції зміни регістру (нижній, верхній, заголовок тощо), а також поведінку за замовчуванням. Використовує вбудовані методи для роботи з рядками Python.
  • Запитує в користувача вибір, перетворюючи введений текст (який є рядком за замовчуванням) на ціле число.

Рядки в Python є незмінними. Тому методи обробки рядків не змінюють оригінальний рядок, а повертають його копію з внесеними змінами. Розглянемо методи Python для роботи з рядками, які ми будемо використовувати:

Метод рядка Опис
lower() Повертає копію рядка, де всі літери перетворені на малі.
upper() Повертає копію рядка, де всі літери перетворені на великі.
title() Повертає копію рядка, де кожне слово починається з великої літери.
swapcase() Повертає копію рядка, де регістр літер змінюється на протилежний (великі на малі, малі на великі).

Наведений нижче фрагмент коду випадково вибирає слово зі списку `word_list` і отримує вибір користувача:

import random

# Список слів для вибору
word_list = ["Python", "програмування", "Привіт", "світ", "контекст", "Перемикач"]

# Випадковий вибір слова зі списку
word = random.choice(word_list)

# Інформування користувача про контекст та доступні опції
print("Вітаю! Ви отримали випадково обране слово.")
print("Виберіть опцію для маніпулювання словом:")
print("1. Малий регістр")
print("2. Великий регістр")
print("3. Регістр заголовка")
print("4. Зміна регістру")
print("5. Поведінка за замовчуванням")

# Отримання вибору користувача
option = int(input("Введіть ваш вибір: "))

Ось приклад, що демонструє, як рядок “Python” змінюється залежно від вибору користувача:

Коли ви запустите цю програму, вам запропонує ввести дані в такому форматі:

Вітаю! Ви отримали випадково обране слово.

Виберіть опцію для маніпулювання словом:
1. Малий регістр
2. Великий регістр
3. Регістр заголовка
4. Зміна регістру
5. Поведінка за замовчуванням

Введіть ваш вибір:

Тепер розглянемо реалізацію різних підходів.

Використання конструкції If-Elif-Else

Цей метод передбачає використання послідовності операторів `if-elif-else` для перевірки вибору користувача на відповідність заданим значенням. Відповідно до вибору користувача виконується певний блок коду.

# if-elif-else

if option == 1:
    result = word.lower()
elif option == 2:
    result = word.upper()
elif option == 3:
    result = word.title()
elif option == 4:
    result = word.swapcase()
else:
    result = word

print(f"Ваше випадкове слово: {word}, а результат: {result}")

Тут:

  • Ми порівнюємо введені користувачем дані з кожною опцією за допомогою операторів `if-elif`.
  • Коли збіг знайдено, виконується відповідний блок коду.
  • Якщо жодна з умов `if-elif` не виконується, виконується блок `else` для типової поведінки.

Ви можете запустити скрипт, ввести вибір та перевірити результат:

Вітаю! Ви отримали випадково обране слово

Виберіть опцію для маніпулювання словом:
1. Малий регістр
2. Великий регістр
3. Регістр заголовка
4. Зміна регістру
5. Поведінка за замовчуванням

Введіть ваш вибір: 2

Ваше випадкове слово: Перемикач, а результат: ПЕРЕМИКАЧ.

Конструкція `if-elif-else` проста у використанні. Але її підтримка може бути ускладнена, особливо коли варіантів вибору стає багато. В нашому прикладі їх 5, але на практиці їх може бути набагато більше. Такі довгі ланцюги `if-elif-else` є ознакою поганого коду, якого слід уникати.

Перейдемо до більш підтримуваного способу реалізації.

Використання відображення словника та функцій як об’єктів першого класу

Для імітації поведінки перемикання вибору можна використовувати словники та функції Python.

✍ Функції Python — це об’єкти першого класу

У Python функції мають статус об’єктів першого класу. Це означає, що з ними можна робити набагато більше, ніж просто викликати:

  • Визначивши функцію, ви можете присвоїти її іншій змінній, використовувати як елемент списку, значення в словнику та багато іншого.
  • Їх також можна передавати як аргументи іншим функціям, а функції можуть повертати інші функції.

У цьому підході ми будемо використовувати словник для зіставлення вибору користувача з відповідними функціями чи діями. Це ефективний спосіб обробки багатьох варіантів, оскільки дозволяє уникнути довгого ланцюжка операторів `if-elif`.

Спочатку визначимо функції для різних операцій з рядками:

# Визначення функцій для кожної опції
def lower_case(word):
    return word.lower()

def upper_case(word):
    return word.upper()

def title_case(word):
    return word.title()

def swap_case(word):
    return word.swapcase()

Далі зробимо наступне:

  • Створимо словник під назвою `options`, де ключі – це вибір користувача, а значення – функції або дії, які потрібно виконати.
  • Використаємо метод `get()` словника, щоб отримати вибрану дію на основі вибору користувача. Якщо вибору немає у словнику, буде застосована дія за замовчуванням, визначена за допомогою лямбда-функції.
  • Потім виконаємо вибрану дію над випадковим словом.
# Збереження функцій у словнику
options = {
    1: lower_case,
    2: upper_case,
    3: title_case,
    4: swap_case,
}

# Використання словника для вибору та виклику відповідної функції
result = options.get(option, lambda x: x)(word)

print(f"Ваше випадкове слово: {word}, а результат: {result}")

Приклад результату:

Вітаю! Ви отримали випадково обране слово.

Виберіть опцію для маніпулювання словом:
1. Малий регістр
2. Великий регістр
3. Регістр заголовка
4. Зміна регістру
5. Поведінка за замовчуванням

Введіть ваш вибір: 4

Ваше випадкове слово: Привіт, а результат: пРИВІТ.

Використання оператора Match-Case

📝 Примітка: для використання оператора `match-case` потрібен Python 3.10 або новішої версії.

Починаючи з Python 3.10, можна використовувати оператор `match` для імітації конструкції, подібної до `switch-case`. Завдяки простому синтаксису оператор `match` забезпечує більш інтуїтивний спосіб обробки кількох випадків. Символ `_` (підкреслення) використовується для визначення дій за замовчуванням.

Ось як можна переписати наш приклад з використанням оператора `match-case`:

  • Ми використовуємо оператор `match` для порівняння введених користувачем даних з різними варіантами.
  • Кожен варіант визначає вибір і код, який потрібно виконати, якщо вибір співпадає.
  • Символ `_` (підкреслення) використовується як випадок за замовчуванням, код виконується, коли жоден інший варіант не підходить.
match option:
    case 1:
        result =  word.lower()
    case 2:
        result = word.upper()
    case 3:
        result = word.title()
    case 4:
        result = word.swapcase()
    case _:
        result = word  # Поведінка за замовчуванням, повертає рядок як є

print(f"Ваше випадкове слово: {word}, а результат: {result}.")

Тепер запустіть скрипт і перевірте результат:

Вітаю! Ви отримали випадково обране слово.

Виберіть опцію для маніпулювання словом:
1. Малий регістр
2. Великий регістр
3. Регістр заголовка
4. Зміна регістру
5. Поведінка за замовчуванням

Введіть ваш вибір: 2
Ваше випадкове слово: світ, а результат: СВІТ.

⚙ Оператор `match` надає зручний спосіб реалізації конструкції перемикання, однак він розроблений для більш складних завдань, пов’язаних зі зіставленням структурних шаблонів, крім простої імітації switch-case.

Підсумки

Підсумуємо різні підходи до реалізації функціональності перемикання в Python:

  • Конструкція `if-elif-else` проста у використанні, але важка для підтримки. Використовуйте її з обережністю і лише коли кількість варіантів вибору невелика.
  • Для імітації поведінки switch-case можна використовувати словники та функції. Додайте різні варіанти та відповідні функції як ключі та значення словника.
  • Оператор `match-case`, представлений в Python 3.10, допомагає реалізувати аналогічну конструкцію `switch-case` за допомогою простого та інтуїтивно зрозумілого синтаксису. Однак він є більш потужним інструментом для зіставлення структурних шаблонів.

Приклади коду з цього підручника можна знайти на GitHub. Якщо ви готуєтеся до співбесіди з кодування, зверніть увагу на підбірку найпопулярніших запитань з Python.