Условные операторы в Python: от простых if до вложенных конструкций
Материал разбирает ветвление в Python для новичков и практиков: от базового if и пары «if–else» до каскада if–elif–else, вложенных условий, тернарного оператора, логических и сравнительных выражений, short-circuit-оценки, а также типичных паттернов и антипаттернов. Вы научитесь писать читаемые проверки, избегать лишней вложенности и выбирать подходящую форму условия под задачу. Поехали! 🚀
Зачем нужны условные операторы
Условные операторы позволяют программе принимать решения на основе булевых выражений: если условие истинно — выполняется один блок кода, иначе — другой. В Python почти любые объекты могут участвовать в проверках «на истинность»: пустые контейнеры и ноль трактуются как False, непустые и ненулевые — как True. Это добавляет гибкости: валидируете входные данные, выбираете алгоритм, пропускаете лишние шаги, обрабатываете особые случаи.
- Истинность/ложность (truthy/falsy). False, None, 0, пустые », [], {}, set() считаются ложными; остальное — истинным.
- Ветвление. Позволяет пройти разными путями исполнения.
- Читаемость. Аккуратные условия облегчают поддержку кода.
Базовый if: синтаксис, отступы и блоки
Python использует отступы в 4 пробела для выделения блоков. После двоеточия идёт блок, который выполняется при истинности условия.
# Простой if
temp = 21
if temp >= 20:
print("Тепло, выходим без куртки")
В блоке можно выполнять несколько операторов. Держите единый стиль и не смешивайте табы с пробелами.
# Несколько выражений в блоке
balance = 500
cost = 200
if balance >= cost:
balance -= cost
print("Покупка оформлена, остаток:", balance)
Пара if–else: двоичный выбор
if–else покрывает два взаимоисключающих сценария. Если условие ложно — срабатывает ветка else.
age = 17
if age >= 18:
msg = "совершеннолетний"
else:
msg = "несовершеннолетний"
print(msg)
Совет: не пишите лишний else, если он не несёт пользы. Часто достаточно вернуть результат в ветке if и продолжить обычный ход функции.
Каскад if–elif–else: множественный выбор
Когда вариантов больше двух, используйте цепочку if–elif–else. Ветви проверяются сверху вниз до первого совпадения.
code = 404
if code == 200:
text = "OK"
elif code == 301:
text = "Moved Permanently"
elif code == 404:
text = "Not Found"
else:
text = "Other"
print(text)
Если вариантов очень много и они «табличные», подумайте о «таблице соответствий» на словаре — читается короче.
# Таблица соответствий вместо «лестницы» elif
responses = {200: "OK", 301: "Moved Permanently", 404: "Not Found"}
text = responses.get(code, "Other")
Вложенные условия: когда можно и когда нельзя
Вложенность уместна, когда проверка одного условия логически зависит от другого. Слишком глубокие «лестницы» ухудшают читаемость.
# Умеренная вложенность
user = {"role": "admin", "active": True}
if user and user.get("active"):
if user.get("role") == "admin":
print("Админский доступ открыт")
else:
print("Обычный пользователь")
Как уменьшить вложенность:
- Guard-clauses. Сначала обрабатывайте «плохие» случаи и выходите из функции.
- Возврат из веток. return внутри условия делает код прямолинейнее.
- Словарь-свитч. Заменяет длинные цепочки elif.
# Guard-clauses вместо глубины
def can_access(user):
if not user: return False
if not user.get("active"): return False
return user.get("role") == "admin"
Тернарный оператор: компактный if–else
Для простых выборов используйте условное выражение — коротко и наглядно, когда обе ветки поверхностные.
# syntax: A if condition else B
age = 20
status = "OK" if age >= 18 else "FAIL"
print(status)
Не злоупотребляйте тернарным выражением: если логика разрастается, обычный if читается лучше.
Логические и сравнительные операторы в условиях
Условия часто комбинируют логику and, or, not и сравнения ==, !=, <, <=, >, >=. В Python есть «цепочки сравнений» и short-circuit-оценка.
- Цепочки сравнений. 0 <= x < 10 эквивалентно двум проверкам с and, но читается лучше.
- Short-circuit. В A and B вторая часть не вычисляется, если A ложна; в A or B — если A истинна.
- in / not in. Проверяет принадлежность элементу в коллекции.
x = 7
if 0 <= x < 10 and x != 5:
print("x в допустимом диапазоне и не равен 5")
# short-circuit для безопасного доступа
user = None
if user and user.get("email"):
print("Отправляем письмо")
Не путайте логические операторы с побитовыми: в Python побитовый — &, а логический — and.
Truthy/Falsy и проверка пустых значений
Часто удобнее проверять объект «как есть», без явного сравнения.
# Неудачно (шумно)
if len(items) > 0:
...
# Лучше (питоничнее)
if items:
...
Отличайте «нет значения» от «нулевого значения». Явно проверяйте None, если ноль и пустая строка допустимы.
# Отличайте None от нуля
count = 0
if count is None:
print("значение ещё не вычислено")
elif count == 0:
print("нулевое значение — это нормально")
Паттерны: диапазоны, словари-свитчи, ранний выход, валидация
Пара приёмов для ежедневных задач 👇
Проверка диапазонов и принадлежности
score = 73
if 90 <= score <= 100:
grade = "A"
elif 75 <= score < 90:
grade = "B"
elif 60 <= score < 75:
grade = "C"
else:
grade = "D"
Словарь вместо каскада elif (таблица соответствий)
def op_add(a, b): return a + b
def op_sub(a, b): return a - b
def op_mul(a, b): return a * b
ops = {"+": op_add, "-": op_sub, "*": op_mul}
op = "*"
result = ops.get(op, lambda a, b: None)(3, 4)
Ранний выход (guard-clauses)
def normalize(email):
if not email: return None
email = email.strip()
if "@" not in email: return None
return email.lower()
Валидация входных данных
raw_age = "18"
age = int(raw_age) if raw_age.isdigit() else None
if age is None or not (0 <= age <= 120):
print("Некорректный возраст")
Антипаттерны и типичные ошибки
- Лишняя вложенность. Выталкивайте ранние проверки наверх и используйте словари-свитчи.
- Сравнение с None через ==. Правильно: is / is not.
- Преждевременная оптимизация. Ясность важнее микровыгод.
- Перегруженные условия. Выносите подвыражения в именованные переменные или функции.
- Смешение табов/пробелов. Единый стиль отступов: 4 пробела.
- & вместо and. Побитовые операции не для логики ветвления.
# Вынос сложного условия в именованные предикаты
is_email = lambda s: s and "@" in s
is_corporate = lambda s: s.endswith("@example.com") if s else False
if is_email(email) and not is_corporate(email):
print("только личные адреса")
Мини-практикум: 4 задания для закрепления
1) Категории по возрасту
age = int(input("Возраст: "))
if age < 0: print("ошибка")
elif age < 12: print("ребёнок")
elif age < 18: print("подросток")
elif age < 65: print("взрослый")
else: print("старше 65")
2) Проверка високосного года
year = int(input("Год: "))
if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0):
print("високосный")
else:
print("обычный")
3) Маршрутизация команды (словарь-свитч)
cmd = input("Команда: ")
def start(): print("стартуем")
def stop(): print("останавливаемся")
def help(): print("команды: start/stop/help")
router = {"start": start, "stop": stop, "help": help}
router.get(cmd, help)()
4) Валидация формы
email = input("Email: ").strip()
password = input("Пароль: ")
if not email or "@" not in email:
print("некорректный email")
elif len(password) < 8:
print("короткий пароль")
else:
print("ок")
Расширения темы: match/case, исключения, логирование
Хотя match/case — сопоставление с образцом, его удобно использовать как альтернативу большому каскаду elif, когда проверяете конкретные значения и формы данных.
# match/case (Python 3.10+)
status = 404
match status:
case 200: print("OK")
case 301: print("Moved")
case 404: print("Not Found")
case _: print("Other")
Рядом с условными конструкциями идут исключения и логирование: ловите «исключительные» ситуации через try/except, а не через громоздкие if; фиксируйте решения логами, чтобы понимать, почему условие сработало. 🐞
import logging; logging.basicConfig(level=logging.INFO)
try:
price = float(input("Цена: "))
if price < 0: raise ValueError("отрицательная цена")
logging.info("ok: %s", price)
except ValueError as e:
logging.error("ошибка ввода: %s", e)
Чек-лист читаемых условий
- Пишите условия коротко и прямо; разбивайте сложные выражения.
- Используйте цепочки сравнений и in, где это уместно.
- Избегайте глубокой вложенности: применяйте guard-clauses и словари.
- Разгружайте условие именованными булевыми переменными/функциями.
- Проверяйте is None вместо == None.
- Для простых выборов — тернарный оператор, но без фанатизма 🙂
Полезные ссылки и итоги
- Документация Python: разделы про выражения и инструкции управления.
- PEP 8: рекомендации по стилю условий и отступов.
- Практика: песочницы и задачники для тренировки логики (Codewars, LeetCode, HackerRank).
Итог: условные операторы — фундамент ветвления программ. Освойте базовый if, двоичный выбор if–else, каскад if–elif–else, применяйте тернарный оператор для коротких присваиваний, держите условия простыми и читаемыми, избегайте глубокой вложенности и используйте «инструменты снижения сложности» — guard-clauses и словари-свитчи. Чем яснее проверки, тем надёжнее и предсказуемее поведение приложения 💡
