Посмотреть пять записей из пятисот и надеяться, что остальные такие же, — компромисс. Цикл его убирает: пройти по всем пятистам стоит столько же, сколько по одной.
Каждый элемент по очереди попадает в тело цикла и прибавляется к накопителю, объявленному заранее.
Цикл по списку
живой пример
статусы = ["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 заказы]— короткая запись цикла со сбором.
Что почитать дальше
- Списки и словари — то, по чему циклы и ходят.
- Функции — чтобы не копировать один и тот же цикл в каждой проверке.
- assert и ошибки — как проверка сообщает о поломке.