Ранее мы изучили условный оператор if. С его помощью можно создавать выполнение с двумя разными вариантами через конструкцию if-else. Однако часто бывает нужно предусмотреть несколько путей выполнения программы — три, четыре, или даже пять. Это называется множественным ветвлением.
Рассмотрим пример. Скажем, что в зависимости от возраста, пользователю рекомендуется определенный вид контента. Есть группы: от 3 до 6 лет, от 6 до 12, от 12 до 16, и 16+. Итого, у нас четыре возрастные группы. Как можно решить эту задачу, если использовать только конструкцию if-else?
Наиболее очевидное решение — последовательно проверять, входит ли указанный возраст в одну из групп, используя последовательно расположенные условные операторы:
old = int(input('Ваш возраст: ')) print('Рекомендовано:', end=' ') if 3 <= old < 6: print('"Заяц в лабиринте"') if 6 <= old < 12: print('"Марсианин"') if 12 <= old < 16: print('"Загадочный остров"') if 16 <= old: print('"Поток сознания"')
Примечание: названия фильмов выводятся в двойных кавычках, поэтому строки в программе определяются с помощью одинарных кавычек.
Этот код выполняет поставленную задачу, но имеет значительный недостаток. Он не оптимален, так как каждая инструкция if работает самостоятельно, не учитывая результаты других. Каждое условие проверяется, даже если в этом нет необходимости. Например, если введено число 10, первый if проверяет условие и передает выполнение следующему if, предназначенному для возраста 6 до 12. Как только это условие выполняется, остальная часть программы должна закрыться.
Однако следующая проверка if не учитывает результат предыдущих операций и остается активной, хотя ее выполнение уже излишне. Аналогично процессору приходится проверять последующие условия, даже если уже ясно, что они ложные. Так как же этого избежать?
Ответ — использовать вложенные условные операторы:
old = int(input('Ваш возраст: ')) print('Рекомендовано:', end=' ') if 3 <= old < 6: print('"Заяц в лабиринте"') else: if 6 <= old < 12: print('"Марсианин"') else: if 12 <= old < 16: print('"Загадочный остров"') else: if 16 <= old: print('"Поток сознания"')
Рассмотрим, как будет выполняться этот вариант кода. Сначала анализируется условие первого, самого внешнего if. Если оно истина, выполнение идет по этому пути, без обращения к блокам else. Таким образом, если условие внешнего if ложное, выполнение переходит к следующему уровню else, который приносит с собой новый if со своим блоком else. Если введенное значение попадает в диапазон от 6 до 12, программа просто выполнит соответствующий блок и завершается, если нет — переходит к следующему уровню else и so on до последней проверки. Это обеспечивает экономию процессорных ресурсов и делает логику программы более правильной.
Теперь появляется вопрос: можно ли еще сильнее упростить многовариантное ветвление, избежав вложенности? Во многих языках, где отступы важны только для удобочитаемости, подобное записывается в таком формате:
if логическое_выражение { … ; } else if логическое_выражение { … ; } else if логическое_выражение { … ; } else { … ; }
На первый взгляд, кажется, что здесь есть только один уровень вложенности и новое добавление else if. На деле, этот if просто вложен в else. Эта же структура может быть представлена иначе:
if логическое_выражение { … ; } else if логическое_выражение { … ; } else if логическое_выражение { … ; } else { … ; }
Таким образом она трактуется интерпретатором. Но первый вариант более понятен для разработки человеком.
В Python же такой подход использовать не получится, поскольку здесь отступы влияют на синтаксис. В Python есть возможность сделать множественное ветвление на уровне одного уровня вложенности с помощью elif, что и рассмотрим.
elif — это сокращение от else if, что можно понимать как "иначе если". Важно знать, что, в отличие от else, в заголовке elif обязательно должно быть указано логическое условие. Давайте перепишем наш пример в if-elif структуре:
old = int (input('Ваш возраст: ')) print('Рекомендовано:', end=' ') if 3 <= old < 6: print('"Заяц в лабиринте"') elif 6 <= old < 12: print('"Марсианин"') elif 12 <= old < 16: print('"Загадочный остров"') elif 16 <= old: print('"Поток сознания"')
Отметим, что в конце, после всех elif, можно использовать ветку else для обработки всех ситуаций, не подпадающих под условия предыдущих блоков. Схематически подход if-elif-…-elif-else можно изобразить так:
Как только выполняется тело if или одного из elif, программа возвращается в основную ветвь (нижний ярко-голубой прямоугольник), и ни else, ни оставшиеся elif не выполняются.
Практическая работа
- Возьмите последний вариант кода программы из урока. Добавьте ветвь else для обработки случаев, когда вводятся числа вне указанных диапазонов. Подумайте, почему в первой версии программы, использовавшей несвязанные if, нельзя было применить else для обработки таких случаев, и приходилось добавлять еще один if.
- Модифицируйте предыдущую программу для обработки исключения ValueError, возникающего при вводе чисел, не являющихся целыми.
- Разработайте программу, запрашивающую у пользователя число. Если оно положительное, вывести 1. Если отрицательное, вывести -1. Если введено 0, вывести 0. Используйте оператор множественного ветвления.