# Циклы и условия в Python: for, while, range, enumerate, break, if/elif и match/case

URL: https://skillaria.top/ru/guides/python/cikly-python

Циклы в Python повторяют действия: for перебирает элементы любой коллекции или диапазона range(), а while выполняется, пока условие истинно. Прервать цикл можно через break, пропустить итерацию — через continue, номер элемента даёт enumerate(). Решения принимают условия if/elif/else, а разбор данных по форме — оператор match/case (с Python 3.10).

Циклы в Python нужны, чтобы повторять действие: пройти по списку покупок, обработать каждую строку файла, спрашивать пользователя, пока он не введёт корректное число. В языке два цикла — `for` и `while`, а принимать решения внутри них помогают условия `if/elif/else` и оператор `match/case`. Разберём каждый инструмент на рабочих примерах.

## Условия: if, elif, else

Условный оператор выполняет блок кода, только если выражение истинно. Блок выделяется отступом в 4 пробела — фигурных скобок в Python нет, и неправильный отступ сразу даёт ошибку `IndentationError`.

```
spent = 4200
limit = 5000

if spent > limit:
    print("Лимит превышен")
elif spent > limit * 0.8:
    print("Осталось меньше 20% бюджета")
else:
    print("Всё в порядке")
```

Ветки `elif` проверяются сверху вниз, и срабатывает только первая подходящая. Поэтому более строгие условия ставьте выше: если бы проверка `spent > limit * 0.8` стояла первой, сообщение о превышении лимита никогда бы не появилось.

### Что считается истиной

В условии не обязательно писать сравнение. Ложными считаются `False`, `None`, ноль (`0`, `0.0`) и пустые коллекции: `""`, `[]`, `{}`. Всё остальное — истина. Поэтому проверка «список не пуст» пишется коротко:

```
expenses = []
if not expenses:
    print("Трат пока нет")
```

Условия объединяют через `and`, `or`, `not`, а диапазон удобно проверять цепочкой сравнений: `if 0 < amount <= 100_000:`. Для короткого выбора значения есть тернарный оператор: `status = "много" if spent > limit else "норма"`.

## Цикл for в Python: синтаксис и примеры

Цикл `for` в Python — это не счётчик, как в C, а перебор элементов. Он берёт по очереди каждый элемент итерируемого объекта: списка, строки, словаря, файла, диапазона. Аналог foreach из других языков — это и есть обычный `for`.

```
expenses = [350, 1200, 89, 4500]
total = 0
for amount in expenses:
    total += amount
print(total)  # 6139
```

Синтаксис цикла for: `for переменная in коллекция:`, затем блок с отступом. Переменная после цикла сохраняет последнее значение — иногда это полезно, но полагаться на это в больших программах не стоит.

### Цикл по строке, списку и словарю

Строка перебирается посимвольно, список — по элементам. Цикл по словарю по умолчанию идёт по ключам; чтобы получить сразу ключ и значение, используйте `.items()`:

```
by_category = {"еда": 3200, "транспорт": 900, "кино": 600}

for category, amount in by_category.items():
    print(f"{category}: {amount} ₽")
```

Для одних значений есть `.values()`. Менять размер словаря во время перебора нельзя — получите `RuntimeError: dictionary changed size during iteration`. Если нужно удалить элементы, перебирайте копию: `for key in list(d):`.

## Функция range: цикл по числам

Когда нужен перебор чисел, на помощь приходит `range()`. Он не создаёт список в памяти, а выдаёт числа по одному, поэтому `range(10**9)` работает мгновенно.

| Вызов | Числа |
| --- | --- |

| `range(5)` | 0, 1, 2, 3, 4 |

| `range(2, 6)` | 2, 3, 4, 5 |

| `range(0, 10, 3)` | 0, 3, 6, 9 |

| `range(5, 0, -1)` | 5, 4, 3, 2, 1 |

Главное правило: правая граница не входит в диапазон. `range(1, 10)` закончится на 9 — это частая причина ошибки «на единицу». Шаг может быть отрицательным, но не нулевым.

```
for i in range(1, 4):
    print(f"День {i}")
# День 1
# День 2
# День 3
```

## enumerate: счётчик в цикле

Новички часто пишут `for i in range(len(items))`, чтобы знать номер элемента. Так работает, но читается хуже. Функция `enumerate()` выдаёт пары «номер, элемент», а параметр `start` задаёт, с какого числа считать:

```
items = ["кофе", "такси", "обед"]
for n, item in enumerate(items, start=1):
    print(n, item)
# 1 кофе
# 2 такси
# 3 обед
```

Для параллельного перебора двух списков есть `zip()`: `for name, price in zip(names, prices):`. Он останавливается на самом коротком списке; с Python 3.10 можно передать `strict=True`, и тогда разная длина вызовет ошибку.

## Цикл while в Python

Цикл `while` повторяет блок, пока условие истинно. Его выбирают, когда число повторений заранее неизвестно: ждём правильного ввода, читаем данные до конца, повторяем запрос до успеха.

```
balance = 10_000
month = 0
while balance > 0:
    balance -= 2_700
    month += 1
print(f"Денег хватит на {month} мес.")  # 4
```

Главная опасность — забыть изменить переменную из условия. Тогда цикл никогда не закончится. Если программа «зависла», нажмите Ctrl+C: Python прервёт выполнение с `KeyboardInterrupt`.

### Бесконечный цикл и do while

Иногда бесконечный цикл в Python пишут намеренно: `while True:` с выходом через `break`. Так же делают цикл с постусловием — в Python нет конструкции `do while`, и её заменяет этот приём: тело выполняется хотя бы один раз, а проверка стоит в конце.

```
while True:
    raw = input("Сумма: ")
    if raw.isdigit():
        amount = int(raw)
        break
    print("Введите целое число")
```

Цикл for бесконечным бывает редко — только если перебирать бесконечный итератор, например `itertools.count()`.

## break и continue: выход из цикла и пропуск итерации

`break` немедленно прерывает цикл, и выполнение идёт дальше, к коду после него. `continue` пропускает остаток текущей итерации и переходит к следующей.

```
expenses = [350, -10, 1200, 0, 99_999, 89]

for amount in expenses:
    if amount  50_000:
        print("Подозрительная сумма, стоп")
        break             # выйти из цикла
    print(amount)
```

Будет напечатано 350 и 1200, затем сообщение — до 89 цикл не дойдёт. Оба оператора действуют только на ближайший цикл, в котором находятся.

### else у цикла

У `for` и `while` есть необычная ветка `else`: она выполняется, если цикл закончился сам, без `break`. Это удобно для поиска:

```
for amount in expenses:
    if amount > 50_000:
        print("Нашли крупную трату")
        break
else:
    print("Крупных трат нет")
```

## Вложенные циклы

Цикл внутри цикла выполняет внутренний полностью на каждой итерации внешнего. Так обходят таблицы, матрицы, перебирают пары.

```
for row in range(1, 4):
    for col in range(1, 4):
        print(row * col, end="\t")
    print()
```

Учтите две вещи. Во-первых, сложность растёт быстро: два вложенных цикла по 10 000 элементов — это 100 миллионов операций. Во-вторых, `break` выходит только из внутреннего цикла. Чтобы прервать оба, вынесите циклы в функцию и используйте `return` — это чище, чем флаги.

## Оператор match/case

Длинную цепочку `if cmd == ... elif ...` с Python 3.10 можно заменить оператором `match` (PEP 634). Это не просто switch: он сопоставляет значение с образцом по форме данных и сразу раскладывает части в переменные.

```
def parse(text):
    match text.split():
        case ["add", item, amount]:
            return f"Добавить {item}: {amount}"
        case ["list"] | ["ls"]:
            return "Показать траты"
        case ["quit"]:
            return "Выход"
        case _:
            return "Неизвестная команда"

print(parse("add Кофе 250"))  # Добавить Кофе: 250
print(parse("add Кофе"))      # Неизвестная команда
```

Шаблон-список `["add", item, amount]` совпадёт только со списком ровно из трёх элементов, первый из которых — `"add"`. Поэтому команда без суммы уходит в ветку `_`, которая ловит всё остальное. Символ `|` объединяет варианты.

### Словари, типы и условие-охранник

Шаблон-словарь проверяет только перечисленные ключи, лишние игнорируются. Запись `int(a)` проверяет тип и захватывает значение, а `if` после шаблона добавляет дополнительное условие (guard):

```
match event:
    case {"type": "expense", "amount": int(a)} if a > 10_000:
        print("Крупная трата", a)
    case {"type": "expense", "amount": int(a)}:
        print("Трата", a)
```

### Главная ловушка match

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

Синтаксис match с 3.10 почти не менялся. В Python 3.15 закрыли небольшую несимметричность: в литеральных шаблонах раньше разрешался только минус перед числом, теперь можно писать и `case +1:`. На более старых версиях такой код даст ошибку синтаксиса.

## Типичные ошибки в циклах

- **Изменение списка во время перебора.** Удаление элементов в `for` пропускает соседние. Лучше собрать новый список: `clean = [x for x in items if x > 0]`.
- **Граница range.** `range(1, n)` не включает `n`.
- **Забытое изменение условия в while** — бесконечный цикл.
- **Склейка строк в цикле через +=** на больших объёмах медленнее, чем `"".join(parts)`.
- **Присваивание вместо сравнения**: `if x = 5` — синтаксическая ошибка, сравнение пишется `==`.

## Задачи на циклы для практики

1. Посчитайте сумму и среднее для списка трат, пропуская отрицательные значения.
2. Выведите таблицу умножения 1–9 вложенными циклами.
3. Спрашивайте у пользователя числа, пока он не введёт пустую строку, затем выведите максимум.
4. Найдите первое число больше 1000 в списке и сообщите, если такого нет (через `for ... else`).
5. Разберите команды `add`, `del`, `list` через `match`.

## Итог

Циклы Python сводятся к двум конструкциям: `for` перебирает элементы коллекции или `range()`, `while` работает, пока выполняется условие. `break` и `continue` управляют ходом цикла, `enumerate()` и `zip()` избавляют от ручных счётчиков, а `if/elif/else` и `match/case` отвечают за решения. Все эти инструменты на примере трекера расходов разобраны на практике в лекции курса по Python.

## FAQ

**Чем for отличается от while в Python?**

for перебирает готовую последовательность и сам знает, когда остановиться, а while повторяется, пока условие истинно. Если число повторений известно или есть коллекция — берите for, если ждёте события — while.

**Как пройти цикл в обратном порядке?**

Используйте reversed(items) для коллекции или range(n - 1, -1, -1) для чисел. Функция reversed не копирует список, а перебирает его с конца.

**Есть ли в Python switch?**

Отдельного switch нет, его роль выполняют цепочка if/elif и оператор match/case, появившийся в Python 3.10. match умеет больше: разбирает списки и словари по форме и захватывает значения.

**Что быстрее — цикл или генератор списка?**

Генератор списка вида [x * 2 for x in items] обычно немного быстрее эквивалентного цикла с append и короче. Для сложной логики с несколькими условиями обычный цикл читается лучше.

**Как выйти сразу из двух вложенных циклов?**

break прерывает только внутренний цикл. Проще всего вынести циклы в функцию и выйти через return.


---
Source: Skillaria.Top (https://skillaria.top)
