Shanraq.org Shanraq.org
Условия: if, elif, else — и число, которого нет
IT

Python: от данных до своей сводки Урок 7 из 56

Условия: if, elif, else — и число, которого нет

Седьмой урок курса по Python. Число само по себе не говорит ничего: 11,4% — это много или мало? Условие сравнивает и выбирает путь. Измерено на инфляции: Казахстан в 2025 году — 11,4%, мир — 3,0%. Плюс главное правило работы с данными: пропуск в ряду — это не ноль, и проверяют его через `is None`.

Зачем это нужно

До сих пор программа считала одно и то же для любых чисел. Настоящая работа с данными начинается там, где числа разные и путь зависит от них: год с пропуском пропустить, а не считать нулём; ряд, где значение выше нормы, отметить; строку с мусором отложить.

Всё это — одна конструкция. Она сравнивает и выбирает, и в ней три слова: if, elif, else.

Сегодня же появляется правило, которое в курсе о данных стоит дороже синтаксиса: отсутствие числа и ноль — не одно и то же. Отчёт, который считает пропуск нулём, ошибается молча, и вы узнаете об этом от читателя.

Сразу целиком

Файл shart.py. Запуск: python shart.py из окружения.

"""Урок 7: условия — на инфляции, которой есть с чем сравниться.

Одно число ничего не значит, пока его не с чем сравнить. Условие — это и есть
сравнение, после которого программа идёт одним путём, а не другим.
"""

# Инфляция за год, %. Числа — из первого урока, Всемирный банк.
# У 2026 года значения нет: год не кончился. Это пропуск, а не ноль.
kz = {2022: 15.0, 2023: 14.5, 2024: 8.7, 2025: 11.4, 2026: None}
world = {2022: 8.1, 2023: 5.8, 2024: 3.0, 2025: 3.0}

here = kz[2025]
there = world[2025]

print("== 2025 год")
print(f"Казахстан: {here} | мир: {there}")
if here is None:
    print("за этот год числа ещё нет")
elif here < there:
    print("ниже мировой")
elif here < 2 * there:
    print("выше мировой, но меньше чем вдвое")
else:
    print("вдвое выше мировой и больше")

print()
print("== 2026 год")
future = kz[2026]
if future is None:
    print("числа ещё нет — сравнивать не с чем")
else:
    print("число есть:", future)

print()
print("== два сравнения в одном условии")
if 2.0 <= there < 4.0:
    print(f"мир: {there} — между двумя и четырьмя")
if here > there and kz[2024] > world[2024]:
    print("Казахстан: выше мировой второй год подряд")

Выводит:

== 2025 год
Казахстан: 11.4 | мир: 3.0
вдвое выше мировой и больше

== 2026 год
числа ещё нет — сравнивать не с чем

== два сравнения в одном условии
мир: 3.0 — между двумя и четырьмя
Казахстан: выше мировой второй год подряд

Разбор

Двоеточие и отступ вместо скобок

if here < there:
    print("ниже мировой")

Двоеточие в конце строки означает «дальше блок». Сам блок задаётся отступом — четырьмя пробелами. В большинстве языков для этого нужны фигурные скобки, в Python их роль играет пустое место слева.

Отсюда единственная ошибка новичка, которая ловится глазами: строка ушла не на тот уровень — и выполняется не тогда, когда вы думали. Редактор ставит четыре пробела сам; смешивать их с табуляцией нельзя, Python на это ругается отдельно.

Образ. Абзац в письме. Вы не пишете «начало абзаца» и «конец абзаца» — вы делаете отступ, и это видно.

elif — не «ещё один if»

Разница, на которой спотыкаются, видна на нашем выводе. Цепочка проверяется сверху вниз: 11,4 — не None, не ниже мировой, не меньше её удвоенной. Ни одно условие не сработало, поэтому дошло до else, и напечаталась одна строка.

Цепочка if — elif — else проверяется сверху вниз и останавливается на первом сработавшем. Остальные не проверяются вовсе.

Три отдельных if — совсем другое:

if here > there:        → сработает
if here > 2 * there:    → тоже сработает

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

else в конце — «во всех остальных случаях». Он не обязателен, но, если его нет, при неподошедших условиях не произойдёт ничего — и это тоже надо решать сознательно.

Пропуска нет — это не ноль

Самая дорогая строка урока:

if future is None:

В ряду за 2026 год стоит None — не потому, что инфляция была нулевой, а потому, что года ещё не было. Это разные вещи, и в отчёте они дают разные ответы.

Проверять это надо именно через is None, а не так:

if future:          → False и для None, и для 0.0

Помните из урока о типах: bool(0.0) — ложь. Год с нулевой инфляцией пройдёт по такой проверке как «нет данных» и молча исчезнет из расчёта. is None спрашивает ровно то, что нужно: значение отсутствует.

Слово is здесь не случайно. Оно сравнивает не значения, а тот же ли это объект, и None в Python существует в единственном экземпляре — поэтому is None и есть правильная проверка.

Два сравнения в одном условии

if 2.0 <= there < 4.0:

Читается как в математике: «от двух включительно до четырёх». В большинстве языков так писать нельзя и приходится составлять there >= 2.0 and there < 4.0; Python понимает цепочку сравнений напрямую и вычисляет there один раз.

and, or и порядок проверки

if here > there and kz[2024] > world[2024]:

and — истина, когда истинны оба; or — когда хотя бы одно; not переворачивает.

Важнее другое: and останавливается на первом ложном, or — на первом истинном. Правое не вычисляется вовсе. Отсюда приём, который дальше в курсе понадобится постоянно:

if value is not None and value > 5:

Сначала убеждаемся, что число есть, и только потом сравниваем. Поменяйте местами — и на пропуске программа упадёт, потому что None > 5 сравнить нельзя.

Почему одно и то же написано трижды

Загляните в программу ещё раз: три блока, и в каждом снова print, снова сравнение. Если бы лет было не три, а тридцать, так писать стало бы невозможно.

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

Карта урока

Карта урока: развилка, цепочка и пропуск

Скажите своими словами

Не подглядывая, ответьте вслух или на бумаге. Ответы — в конце урока.

  1. Почему из цепочки if — elif — else печатается одна строка, а из трёх отдельных if — две?
  2. Чем if value is None отличается от if not value и почему в данных это важно?
  3. Что делает and, когда левая часть оказалась ложной?

Разминка

Три коротких шага перед заданием: предсказать, дописать, починить. Ответы — в конце урока, но сначала ответьте сами.

1. Предскажите. Что напечатает эта программа? Скажите вслух, потом запустите.

value = None
if value == 0:
    print("ноль")
elif value is None:
    print("числа нет")
else:
    print("число:", value)

2. Заполните пропуск. Вместо ... поставьте условие «отличается от среднего не больше чем на 5% в любую сторону».

value = 8.3
average = 8.0
if ...:
    print("около среднего")
else:
    print("далеко от среднего")

3. Почините. Эта программа падает на второй паре. Найдите строку, из-за которой это происходит, и сделайте так, чтобы напечатались обе.

kz = {2024: 8.7, 2025: None}
for year, value in kz.items():
    if value > 8:
        print(year, "выше восьми")
    elif value is None:
        print(year, "числа нет")

Задание

Обязательное. Дано:

prices = {"январь": 520.0, "февраль": 580.0, "март": None, "апрель": 498.0}

Напечатайте среднее по месяцам, у которых есть число, а потом каждый месяц с пометкой: «около среднего», если цена отличается от среднего не больше чем на 5% (ровно 5% — тоже «около»), иначе «выше среднего» или «ниже среднего»; месяц без числа — «данных нет». Проверки идут в этом порядке: сначала пропуск, потом «около», потом «выше» и «ниже».

Ожидаемый вывод:

среднее: 532.67
январь: 520.0 — около среднего
февраль: 580.0 — выше среднего
март: данных нет
апрель: 498.0 — ниже среднего

Готово, когда: вывод совпадает построчно; среднее посчитано по трём месяцам, а не по четырём; ни одно сравнение не встречает None.

На своих данных. Возьмите три своих числа — цены одного товара в разных магазинах, или свою инфляцию по чекам, или что угодно измеримое. Сравните каждое со средним и напечатайте цепочкой if — elif — else: «дешевле среднего», «около среднего» (в пределах 5%), «дороже среднего». Одно из трёх чисел сделайте None и проверьте его первым — до всех сравнений.

По желанию.

  • Замените цепочку тремя отдельными if и посмотрите, сколько строк напечатается.
  • Напишите условие с and, где правая часть упадёт, если поставить её первой.
  • Проверьте на своём ряду: сколько лет из пяти были выше мировой инфляции?

Куда это встанет в проекте

Сводка перестаёт считать всё подряд. С этого урока у неё появляется разбор: год с пропуском не попадает в среднее, значение выше нормы отмечается, а строка с мусором откладывается в сторону вместо того, чтобы испортить итог.

Долги. Условия пока написаны по одному на каждый год — с циклом это станет тремя строками. И «выше нормы» мы решаем на глаз: где проходит норма, у нас нигде не записано.

Ответы

Показать ответы

На вопросы

  1. Потому что цепочка проверяется сверху вниз и останавливается на первом сработавшем условии: остальные не проверяются вовсе. Отдельные if — независимые вопросы, и сработать может каждый.
  2. is None спрашивает, отсутствует ли значение. not value истинно и для None, и для нуля, и для пустой строки — год с нулевой инфляцией по такой проверке исчезнет из расчёта как «нет данных».
  3. Ничего: правая часть не вычисляется. Поэтому value is not None and value > 5 безопасно, а обратный порядок падает на пропуске.

К разминке

  1. числа нет. None == 0 — это False: пропуск не равен нулю, поэтому первая ветка не срабатывает, а вторая проверяет is None и попадает.
числа нет
  1. abs(value - average) <= average * 0.05. Модуль разницы — это и есть «в любую сторону», а <= включает ровно 5%: границу нужно решить один раз и записать, иначе два человека получат разные ответы на одних данных.
value = 8.3
average = 8.0
if abs(value - average) <= average * 0.05:
    print("около среднего")
else:
    print("далеко от среднего")
около среднего
  1. Виновата не строка с None, а порядок: value > 8 проверяется первым, и на 2025 годе сравнение встречает NoneTypeError. Пропуск проверяют до всех сравнений:
kz = {2024: 8.7, 2025: None}
for year, value in kz.items():
    if value is None:
        print(year, "числа нет")
    elif value > 8:
        print(year, "выше восьми")
2024 выше восьми
2025 числа нет

Источники

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Проверить задание

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

Чтобы проверить, нужно войти. Войти

Комментарии (0)

Пока нет комментариев. Будьте первым.