К содержанию

Модуль 2 · Урок 2.2

Ветвление: if, elif и else

Как программа выбирает действие по условию, когда нужны elif, а когда отдельные if.

5 задач

В прошлом уроке условия давали ответ True или False. Теперь программа будет по этому ответу выбирать, какие строки выполнять: это делает инструкция if. Начнём с одной проверки, соберём цепочку из нескольких, а в конце начнём новую сквозную задачу курса — сумму и наибольшее из нескольких чисел.

if и else

if выполняет блок строк, только если условие истинно. Пусть доставка стоит 300 рублей, но при заказе от 2000 рублей она бесплатна:

order_total = 2400delivery = 300if order_total >= 2000:    delivery = 0print(delivery)
0

Строка с if заканчивается двоеточием. Строки под ней с отступом в четыре пробела — это блок: они выполняются, только если условие истинно. Строка без отступа после блока — уже не часть if: print(delivery) выполняется всегда. При сумме 1500 блок пропускается, и программа напечатает 300.

Когда нужно выбрать одно из двух действий, добавляют else — «иначе»:

order_total = 1500if order_total >= 2000:    delivery = 0else:    delivery = 300print(delivery)
300

Блок else выполняется, когда условие if ложно. Из двух блоков выполняется ровно один:

Точкой отмечены выполненные строки. При сумме 2400 условие истинно: выполнен блок if, блок else пропущен. При 1500 — наоборот. Строка print без отступа выполняется в обоих случаях.

Отступ — часть смысла программы. По нему Python понимает, где кончается блок. В PyCharm после двоеточия нажми Enter — отступ появится сам; клавиша Tab вставляет те же четыре пробела. Если отступ пропустить, Python остановится ещё до запуска — это синтаксическая ошибка из первого урока:

if 5 > 3:print("да")
IndentationError: expected an indented block after 'if' statement on line 1

Цепочка elif

elif проверяет следующий случай, только если предыдущие не подошли. Уровень ученика по баллу: от 85 — высокий, от 60 — средний, ниже — начальный. Нажми «Запуск» в шапке примера и пройди программу по шагам:

score = 73if score >= 85:    level = "высокий"elif score >= 60:    level = "средний"else:    level = "начальный"print(level)
средний

elif — «иначе если»: следующая проверка, если предыдущие не подошли. Проверка score >= 85 дала False, score >= 60 — True, и до else дело уже не дошло. Цепочка выбирает ровно одну ветку. Во вторую ветку попадают баллы от 60 до 84: верхняя граница следует из того, что первая проверка не прошла. Проверим границы:

БаллУровеньПочему
85высокий>= включает саму границу
84среднийпервая проверка не прошла, вторая прошла
60среднийграница второй проверки
59начальныйне прошла ни одна проверка

Если сначала проверить score >= 60, а потом score >= 85, высокий балл захватит первая ветка: для 90 получится «средний», а ветка «высокий» не выполнится никогда. Поэтому порядок проверок выводят из условий: от самой строгой к самой мягкой.

Слева балл 73 проходит проверки сверху вниз: первая даёт «нет», вторая — «да», остальное не рассматривается. Справа проверки переставлены: балл 90 уходит в «средний» на первой же проверке, и до «высокий» не доходит никакой балл.

Отдельные if

Если у значения может быть несколько признаков сразу, нужны отдельные if.

n = 12if n % 2 == 0:    print("чётное")if n % 3 == 0:    print("делится на 3")
чётное делится на 3

Будут напечатаны обе строки: каждая проверка независима. Если заменить второй if на elif, после успешной первой проверки вторая даже не выполнится: цепочка if–elif выбирает не больше одной ветки.

Одна и та же проверка для n = 12. Слева два отдельных if: выполнены обе ветки. Справа elif: первая ветка сработала, и вторая проверка пропущена.

Значение на каждом пути

Имя должно получить значение на каждом пути, где оно понадобится. Здесь result получает значение и в ветке if, и в ветке else:

x = -2if x > 0:    result = "положительное"else:    result = "неположительное"print(result)
неположительное

Если убрать else, при x = -2 присваивание не выполнится, и имени result не будет:

x = -2if x > 0:    result = "положительное"print(result)
NameError: name 'result' is not defined

Для простого выбора одного из двух значений есть условное выражение значение if условие else другое:

x = -2absolute = x if x >= 0 else -xprint(absolute)
2

Сначала проверяется условие, затем вычисляется только выбранная часть. Для действий из нескольких строк обычный if читается лучше.

Сквозная задача

Новая сквозная задача курса: сумма и наибольшее из нескольких чисел. Модуль 1 шёл на тетрадях. С этого урока через весь курс пройдёт другая задача: найти сумму и наибольшее из чисел 5, −2, 10, 7. С каждым модулем решение будет короче, а данных — больше. Сейчас у нас есть только переменные и if, поэтому каждое число получает своё имя.

Сумма — просто выражение. Наибольшее ищут так: первое число запоминают как лучшее, а каждое следующее сравнивают с лучшим и, если оно больше, делают лучшим его. Пройди программу по шагам и следи за best:

a = 5b = -2c = 10d = 7total = a + b + c + dbest = aif b > best:    best = bif c > best:    best = cif d > best:    best = dprint(total, best)
20 10

Здесь нужны отдельные if, а не elif: каждое число сравнивается с лучшим на данный момент, и проверить нужно все. Для тысячи чисел так писать нельзя: понадобилась бы тысяча имён и тысяча if. Это решат циклы следующего модуля.

Начало — из данных

Лучшее начинают с первого числа данных, а не с нуля. Проверим на отрицательных числах:

a = -5b = -2c = -9best = aif b > best:    best = bif c > best:    best = cprint(best)
-2

Если начать с best = 0, все отрицательные числа проиграют нулю, которого среди данных нет: программа напечатала бы 0. Равные числа тоже не мешают: при равенстве > не срабатывает, и лучшим остаётся прежнее.

Итог

Теперь программа умеет выбирать, какие строки выполнять. Вот что из этого понадобится в каждом следующем уроке.

  • ifВыполняет блок с отступом, только если условие истинно; строка без отступа — уже после ветвления.
  • elseБлок «иначе»: из двух блоков выполняется ровно один.
  • elifСледующая проверка, если предыдущие не подошли. Цепочка выбирает ровно одну ветку; проверки — от самой строгой.
  • Отдельные ifНезависимые признаки проверяют отдельными if: могут сработать оба.
  • ОтступЧетыре пробела после двоеточия; пропуск — IndentationError.
  • Каждый путьИмя должно получить значение на каждом пути, иначе NameError.
  • a if c else bУсловное выражение: выбор одного из двух значений.
  • НаибольшееЛучшее — первое число данных; каждое следующее сравнивают с лучшим отдельным if.

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1

Что напечатает программа?

x = 5if x > 10:    print("много")print("готово")
ОтветСкрыть ответ
Ответ

Только «готово»: условие ложно, блок пропущен, а print("готово") без отступа выполняется всегда.

Вопрос 2

Найди наибольшее из чисел 4, 4 и −1 программой из урока. Что изменится, если начать best с нуля, а числа будут −5, −2 и −9?

ОтветСкрыть ответ
Ответ

4. С нулевым началом для −5, −2, −9 получится 0 вместо −2.

Вопрос 3

При n = 30 что напечатает программа с двумя отдельными if из урока? А если второй if заменить на elif?

ОтветСкрыть ответ
Ответ

Обе строки: «чётное» и «делится на 3». С elif — только «чётное».

Вопрос 4

В цепочке переставили проверки: сначала score >= 60, потом score >= 85. Какой уровень получат баллы 59 и 100? При каком балле получится «высокий»?

ОтветСкрыть ответ
Ответ

Начальный и средний. «Высокий» не получится ни при каком балле: до проверки score >= 85 доходят только баллы меньше 60.

Вопрос 5

Запиши условным выражением строку "чётное" или "нечётное" для числа n и вычисли её для 15.

ОтветСкрыть ответ
Ответ

"чётное" if n % 2 == 0 else "нечётное"; для 15 — «нечётное».

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Доставка при сумме 1999 и 2000

Запусти программу дважды: сначала введи 1999, затем 2000. Запиши оба результата.

order_total = int(input())if order_total >= 2000:    delivery = 0else:    delivery = 300print(delivery)

Запишите два числа через пробел: для 1999, затем для 2000.

Уровни с новыми границами

Границы уровней поменяли: от 90 — высокий, от 70 — средний, ниже — начальный. Запусти программу четыре раза и введи 90, 89, 70 и 69.

score = int(input())if score >= 90:    print("высокий")elif score >= 70:    print("средний")else:    print("начальный")

Запишите четыре уровня через пробел в порядке баллов: 90, 89, 70, 69.

Какая ошибка остановила программу?

Программа остановилась с ошибкой. Какой тип ошибки стоит в последней строке сообщения?

x = 5if x < 0:    result = "минус"print(result)

Запишите тип ошибки — слово перед двоеточием в последней строке сообщения.

Напиши программу: високосный или обычный год

Напиши программу: вводится год, программа печатает високосный или обычный. Запусти её дважды — для 1900 и для 2024 — и запиши оба ответа.

Запишите два слова через пробел: для 1900, затем для 2024.

Напиши программу: можно ли сложить треугольник

Напиши программу: вводятся три длины отрезков на отдельных строках. Программа печатает да, если из них можно сложить треугольник (каждая сторона меньше суммы двух других), иначе нет. Запусти её дважды: введи 3, 4, 5, затем 1, 2, 3.

Запишите два слова через пробел: для 3, 4, 5, затем для 1, 2, 3.