if/else в Python — условные конструкции для аналитика

Коротко

if/else — основа управления потоком в Python. Аналитики используют условия постоянно: категоризация пользователей, фильтрация данных, валидация входных параметров. На собеседованиях спрашивают про truthy/falsy, тернарный оператор, разницу == и is, цепочки сравнений.

if — базовый синтаксис

Блок кода выполняется, если условие истинно. Отступ — 4 пробела.

revenue = 1_500_000

if revenue > 1_000_000:
    print('Выручка выше миллиона')

Без фигурных скобок, без точек с запятой — только отступы. Забыл отступ — получил IndentationError.

if/else

conversion_rate = 0.02

if conversion_rate >= 0.03:
    status = 'норма'
else:
    status = 'ниже целевого'

if/elif/else

elif — сокращение от «else if». Проверки идут сверху вниз, срабатывает первое истинное условие.

score = 78

if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
else:
    grade = 'F'

# grade = 'C'

Порядок важен. Если поставить score >= 70 первым — до проверки на 90 дело не дойдёт.

Операторы сравнения

x == y   # равно
x != y   # не равно
x > y    # больше
x < y    # меньше
x >= y   # больше или равно
x <= y   # меньше или равно
x in y   # входит в коллекцию
x not in y  # не входит
x is y   # один и тот же объект
x is not y  # разные объекты

Python поддерживает цепочки сравнений — это удобно и читаемо:

age = 25
if 18 <= age < 65:
    print('Трудоспособный возраст')

# Эквивалент: if age >= 18 and age < 65

Логические операторы: and, or, not

has_premium = True
days_active = 30

if has_premium and days_active > 7:
    segment = 'активный премиум'

if not has_premium or days_active < 3:
    segment = 'нужна реактивация'

and возвращает первое ложное значение или последнее. or — первое истинное или последнее. Это используют для значений по умолчанию:

username = input_name or 'Аноним'

Тернарный оператор

Однострочная запись if/else. Удобна для простых присваиваний.

status = 'premium' if has_subscription else 'free'

# Эквивалент:
if has_subscription:
    status = 'premium'
else:
    status = 'free'

Практический пример с pandas:

import pandas as pd

df['segment'] = df['revenue'].apply(
    lambda x: 'high' if x > 10000 else 'low'
)

Не вкладывайте тернарные операторы друг в друга — читаемость падает катастрофически.

Truthy и falsy значения

Python считает ложными (falsy): False, 0, 0.0, None, '' (пустая строка), [] (пустой список), {} (пустой словарь), set(), ().

Всё остальное — истинное (truthy).

data = []

# Плохо
if len(data) == 0:
    print('Нет данных')

# Хорошо (pythonic)
if not data:
    print('Нет данных')
result = None
if result is None:
    print('Результат отсутствует')

С None всегда сравниваем через is, не ==. Это стандарт PEP 8 и частый вопрос на собесе.

Вложенные условия

def categorize_user(revenue, days_since_reg):
    if revenue > 0:
        if days_since_reg <= 30:
            return 'новый платящий'
        else:
            return 'старый платящий'
    else:
        if days_since_reg <= 30:
            return 'новый бесплатный'
        else:
            return 'нужна реактивация'

Глубокая вложенность — антипаттерн. Лучше переписать через ранний return или lambda:

def categorize_user(revenue, days_since_reg):
    if revenue <= 0 and days_since_reg > 30:
        return 'нужна реактивация'
    if revenue <= 0:
        return 'новый бесплатный'
    if days_since_reg <= 30:
        return 'новый платящий'
    return 'старый платящий'

match/case (Python 3.10+)

Структурное сопоставление — аналог switch/case из других языков, но мощнее.

def get_topic_name(topic_id):
    match topic_id:
        case 'sql':
            return 'SQL'
        case 'python':
            return 'Python'
        case 'ab_test':
            return 'A/B-тесты'
        case _:
            return 'Неизвестная тема'

_ — wildcard, срабатывает, если ничего не подошло. match/case умеет разбирать структуры — списки, словари, классы — но это выходит за рамки типичного собеседования на аналитика.

Примеры для аналитика

Категоризация метрики:

def classify_retention(rate):
    if rate >= 0.40:
        return 'отличный'
    elif rate >= 0.20:
        return 'средний'
    else:
        return 'низкий'

Валидация входных данных:

def validate_date_range(start, end):
    if start is None or end is None:
        raise ValueError('Обе даты обязательны')
    if start > end:
        raise ValueError('Начало позже конца')
    if (end - start).days > 365:
        raise ValueError('Диапазон больше года')

Фильтрация в list comprehension:

users = [
    {'name': 'Анна', 'premium': True, 'score': 85},
    {'name': 'Борис', 'premium': False, 'score': 92},
    {'name': 'Вика', 'premium': True, 'score': 45},
]

top_premium = [
    u['name'] for u in users
    if u['premium'] and u['score'] > 60
]
# ['Анна']

Частые ошибки

= вместо == — присваивание вместо сравнения. Python выбросит SyntaxError в if (в отличие от C).

# Ошибка
if x = 5:  # SyntaxError

# Правильно
if x == 5:

Сравнение с True/False через ==:

# Плохо
if is_active == True:

# Хорошо
if is_active:

Мутабельный аргумент по умолчанию в функциях с условиями:

# Плохо — список один на все вызовы
def add_filter(filters=[]):
    filters.append('new')
    return filters

# Хорошо
def add_filter(filters=None):
    if filters is None:
        filters = []
    filters.append('new')
    return filters

Вопросы с собеседований

Что выведет код?

x = []
if x:
    print('A')
else:
    print('B')

Ответ: B. Пустой список — falsy.

Что вернёт выражение 0 or '' or None or 'hello' or 42?

Ответ: 'hello'. or возвращает первое truthy значение.

Чем отличается == от is?

== сравнивает значения, is — идентичность объектов (один и тот же адрес в памяти). a = [1, 2]; b = [1, 2]a == b истинно, a is b ложно.

Можно ли написать if 1 < x < 10 в Python?

Да. Python поддерживает цепочки сравнений. Эквивалент: if 1 < x and x < 10.

Что такое walrus-оператор?

:= (Python 3.8+) — присваивание внутри выражения:

if (n := len(data)) > 100:
    print(f'Слишком много строк: {n}')

FAQ

Сколько elif может быть в одном блоке?

Сколько угодно. Но если их больше 4-5, рассмотрите словарь-маппинг или match/case.

Когда использовать match/case вместо if/elif?

Когда сравниваете одну переменную с набором конкретных значений. Для диапазонов и сложных условий if/elif удобнее.

Есть ли switch в Python?

До версии 3.10 — нет. С 3.10 появился match/case. Для простых маппингов используйте словарь: result = mapping.get(key, default).

Что дальше

Условия — одна из базовых тем Python. Чтобы углубиться: типы данных, циклы for и while, lambda-функции. Все темы для подготовки — на странице примеров и в Python-тренажёре.

Потренируйте условные конструкции на реальных задачах с собеседований — откройте тренажёр.