Основы

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

Обновлено: · Skillaria.Top

Циклы в 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 <= 0:
        continue          # пропустить итерацию цикла
    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.

Частые вопросы

Чем 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.

Разберите тему на видео

Эта тема подробно разобрана с практикой в курсе «Python 3.15: от новичка до профи».

Перейти к курсу