← назад к разделу

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

for позиция in позиции: итого += цена × количество 1 × 4990 2 × 890 1 × 12990 итогонакопитель итого = 0 объявляют ДО цикла внутри — обнулялось бы на каждом круге, и в конце осталась бы последняя позиция

Каждый элемент по очереди попадает в тело цикла и прибавляется к накопителю, объявленному заранее.

Цикл по списку

живой пример

статусы = ["NEW", "PAID", "SHIPPED"]

for статус in статусы:
    print(статус)
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Читается буквально: «для каждого статуса в статусах — напечатай статус». Переменную статус заводить заранее не нужно: цикл сам подставляет в неё на каждом круге очередной элемент.

Тело цикла — со сдвигом вправо, как у if. Что сдвинуто, то повторяется; что не сдвинуто, выполнится один раз после цикла.

Отработать здесь: Пройти по списку циклом

Накопить сумму

Сумму по списку собирают в отдельную переменную — накопитель. Весь вопрос в том, где её объявить.

живой пример

# так не надо
позиции = [{"qty": 1, "price": 4990}, {"qty": 2, "price": 890}]

for позиция in позиции:
    итого = 0
    итого += позиция["qty"] * позиция["price"]

print(итого)     # 1780 — осталась только последняя позиция
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

живой пример

# так надо
позиции = [{"qty": 1, "price": 4990}, {"qty": 2, "price": 890}]

итого = 0
for позиция in позиции:
    итого += позиция["qty"] * позиция["price"]

print(итого)     # 6770
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Накопитель внутри цикла обнуляется на каждом круге, и до конца доживает только последнее значение. Ошибки при этом нет — просто неверное число, и заметно оно лишь по результату. Запись итого = итого + x сокращают до итого += x.

Отработать здесь: Посчитать сумму по позициям заказа · Сумма оплаченных заказов

Счётчик

Счётчик устроен так же, только прибавляют единицу:

живой пример

заказы = [
    {"id": "ord-042", "status": "PAID"},
    {"id": "ord-043", "status": "CANCELLED"},
]

отменённых = 0
for заказ in заказы:
    if заказ["status"] == "CANCELLED":
        отменённых += 1

print(отменённых)     # 1
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Здесь двойной сдвиг: if стоит внутри for, а его тело — ещё правее. Сдвиги показывают вложенность.

Отработать здесь: Посчитать заказы по статусу

Цикл по словарю

По словарю ходят так же — по ключам или сразу по парам:

живой пример

заказ = {"id": "ord-042", "status": "PAID", "total": 4990}

for ключ in заказ:
    print(ключ)

for ключ, значение in заказ.items():
    print(f"{ключ} = {значение}")
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

items() отдаёт готовую пару, и её разбирают в две переменные сразу. Так удобно проверять все поля разом — например, что ни одно из них не пустое.

Отработать здесь: Перебрать ключи и значения

Остановиться раньше

Если нужный элемент уже нашёлся, дочитывать список до конца незачем.

живой пример

заказы = [
    {"id": "ord-042", "status": "PAID"},
    {"id": "ord-043", "status": "CANCELLED"},
]

найден = None
for заказ in заказы:
    if заказ["id"] == "ord-043":
        найден = заказ
        break          # дальше искать незачем

print(найден)
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

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

живой пример

заказы = [
    {"id": "ord-042", "status": "DRAFT"},
    {"id": "ord-043", "status": "PAID"},
]

for заказ in заказы:
    if заказ["status"] == "DRAFT":
        continue       # черновики не считаем
    print(заказ["id"])
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Когда нужен номер элемента

Иногда рядом с элементом нужен и его порядковый номер — например, чтобы пронумеровать строки при печати.

живой пример

заказы = ["ord-042", "ord-043", "ord-044"]

# так не надо: ходить по номерам и доставать элемент из списка
for i in range(len(заказы)):
    print(i + 1, заказы[i])

# так надо: enumerate отдаёт номер вместе с элементом
for номер, заказ in enumerate(заказы, start=1):
    print(номер, заказ)
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Печатают обе записи одно и то же, но во второй нечем промахнуться: номер приходит вместе с элементом.

Собрать новый список

Частая задача: из списка словарей достать одно поле.

живой пример

заказы = [
    {"id": "ord-042", "status": "PAID"},
    {"id": "ord-043", "status": "CANCELLED"},
]

номера = []
for заказ in заказы:
    номера.append(заказ["id"])

print(номера)
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Короткая запись того же самого называется списковым включением — в чужом коде она встречается часто:

живой пример

заказы = [
    {"id": "ord-042", "status": "PAID"},
    {"id": "ord-043", "status": "CANCELLED"},
]

номера = [заказ["id"] for заказ in заказы]
отменённые = [заказ for заказ in заказы if заказ["status"] == "CANCELLED"]
print(номера)
print(отменённые)
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Три дня бесплатно →

Пишите как удобнее: длинная форма понятнее, короткая компактнее.

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

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

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

Коротко

  • for элемент in список проходит по всем элементам; заводить переменную заранее не нужно.
  • Накопитель (итого = 0, счётчик = 0) объявляют до цикла, иначе он сбрасывается на каждом круге.
  • По словарю ходят через .items() — сразу пара «ключ, значение».
  • break выходит из цикла, continue пропускает круг.
  • enumerate даёт номер вместе с элементом, а списковое включение [заказ["id"] for заказ in заказы] — короткая запись цикла со сбором.

Что почитать дальше