Счётчики и аккумуляторы в циклах Python
Сумма чека, число совпадений, лучший результат: переменная, объявленная до цикла и копящая значения внутри, — приём старше языков. Разбираем счётчики, суммы, максимумы и их ловушки.
Редакция Питоники
Посчитать сумму покупок, число совпадений, лучший результат — задачи, в которых цикл не просто перебирает, а накапливает. Для этого у программистов есть приём старше языков высокого уровня: переменная-аккумулятор. Объявили до цикла, копили внутри, прочитали после — разберём суммы, счётчики, максимумы и главные ловушки каждого.
Аккумулятор: сумма
Чек из четырёх покупок — сложим все цены через цикл:
prices = [89, 42, 590, 60]
total = 0
for p in prices:
total += p
print(total)
781
total объявлен до цикла со стартовым нулём. На каждой итерации total += p прибавляет текущую цену к накопленному; запись total += p — короткая форма total = total + p. К выходу из цикла в total лежит сумма: 781. Место аккумулятора запомните раз и навсегда: старт — до цикла, накопление — внутри, чтение — после.
Счётчик: считаем события
Теперь считаем не значения, а события: сколько дней температура перевалила за порог.
temps = [18, 25, 30, 11, 27]
hot = 0
for t in temps:
if t >= 25:
hot += 1
print(hot)
3
Счётчик — тот же аккумулятор, только шаг всегда единица. hot растёт не на значение элемента, а на сам факт: температура попала в порог. Схема совпадает до буквы: объявили с нулём до цикла, увеличили внутри, прочитали после.
Фильтр перед накоплением — частый гость: посчитаем сумму только по недорогим позициям.
prices = [89, 42, 590, 60]
total = 0
for p in prices:
if p >= 100:
continue
total += p
print(total)
191
Дорогая позиция отсеивается continue — и в сумму попадает только дешёвое: 89 + 42 + 60. Условие перед накоплением — самый короткий путь от простого подсчёта к подсчёту с правилами.
Два аккумулятора за один проход
Частая задача — среднее арифметическое. Наивный способ: сначала посчитать сумму, потом посчитать количество, потом разделить. Списки небольшие, и это никто не заметит. Но правильнее копить обе величины за один проход: аккумуляторов два, а данных перебираем один раз.
temps = [18, 25, 30, 11, 27]
total = 0
count = 0
for t in temps:
total = total + t
count = count + 1
print('среднее:', total / count)
среднее: 22.2
22.2 — это 111, делённое на 5. Оба аккумулятора объявлены до цикла и растут внутри. Если бы мы считали сумму одним циклом, а количество через len, результат совпал бы, но список пришлось бы перебирать дважды. На больших данных это удвоенное время, на маленьких — пара лишних строк.
Максимум и минимум вручную
Аккумулятор умеет копить не только суммы. Найдём самый жаркий день:
temps = [18, 25, 30, 11, 27]
best = temps[0]
for t in temps:
if t > best:
best = t
print(best)
30
Стартуем с первого элемента: best = temps[0]. Дальше каждый претендент сравнивается с чемпионом — кто больше, тот и новый чемпион. К концу перебора в best лежит максимум.
А вот что будет, если стартовать с нуля — на первый взгляд тоже сойдёт:
lows = [-12, -5, -30]
best = 0
for t in lows:
if t > best:
best = t
print(best)
0
Напечатан ноль — числа из списка его не перебили: ни одно не оказалось больше нуля, чемпион остался фантомом. Правильный ответ -5 так и не выбрался из списка.
Максимум и минимум за один проход
Иногда нужны оба экстремума сразу, а данных — один и тот же список. Два отдельных цикла работают, но это два прохода по одним и тем же числам. Проще объявить двух кандидатов и сравнивать с обоими за один шаг.
temps = [18, 25, 30, 11, 27]
best = temps[0]
worst = temps[0]
for t in temps:
if t > best:
best = t
if t < worst:
worst = t
print(best, worst)
30 11
Оба кандидата стартуют с первого элемента — это то же правило, что и для максимума в одиночку: ноль был бы нечестным отправным значением на списках с отрицательными числами. Две проверки внутри тела не мешают друг другу: на каждом шаге число сравнивается и с максимумом, и с минимумом.
Ловушка обнуления
Вторая классическая ошибка — объявить аккумулятор внутри цикла. Код выглядит почти правильно:
prices = [89, 42, 590]
for p in prices:
total = 0
total += p
print(total)
590
Напечатана 590 — только последняя цена. Обнуление внутри тела стирает накопленное на каждой итерации: к концу цикла в total лежит лишь вклад последнего шага. Вся сумма 721 погибла по дороге. Лечится переносом одной строки — total = 0 должен встать до for.
Словарь-аккумулятор
Аккумулятором может быть не только число. Словарь, в котором ключ — это категория, а значение — счётчик, умеет считать группы за один проход. Это ровно то, что делает подсчёт слов в тексте, заказов по товарам или ошибок по кодам.
words = ['кот', 'ёж', 'кот', 'пёс', 'кот']
counter = {}
for w in words:
if w in counter:
counter[w] = counter[w] + 1
else:
counter[w] = 1
print(counter)
{'кот': 3, 'ёж': 1, 'пёс': 1}Разбор логики: если ключа ещё нет — создаём его со значением 1, если есть — увеличиваем на единицу. Словарь не пришлось объявлять заранее: первый же прошедший элемент создаст свой ключ. Порядок ключей в выводе — порядок первого появления, а не алфавитный.
Счётчик удобно сочетать с continue — так за один проход считают сразу две разные величины:
grades = [5, 3, 5, 2, 5, 4]
fives = 0
twos = 0
for g in grades:
if g == 5:
fives = fives + 1
continue
if g == 2:
twos = twos + 1
print('пятёрок:', fives, 'двоек:', twos)
пятёрок: 3 двоек: 1
Три пятёрки и одна двойка — цикл прошёл все шесть оценок. Continue здесь работает как «дальше не смотри»: после подсчёта пятёрки цикл сразу переходит к следующей оценке, не проверяя её на двойку. Разделение на два счётчика читается легче, чем одно условие с двумя проверками внутри.
Готовые инструменты: sum, max, min
Простые накопления встроены в язык — и под капотом у них тот же цикл с аккумулятором:
temps = [18, 25, 30, 11, 27]
print(sum(temps))
print(max(temps), min(temps))
111 30 11
sum складывает, max и min находят экстремумы — три строки вместо трёх циклов. Руками аккумуляторы пишут, когда нужно больше: фильтр перед накоплением, несколько величин за один проход, свой критерий сравнения. Среднее, например, считают двумя аккумуляторами сразу: сумма плюс количество, потом деление.
Счётчик умеет и страховать циклы: ограничение попыток в while — классический приём против зависаний, он подробно разобран в уроке про бесконечный цикл. А вот как выглядит накопление с живым вводом — кассир вводит цены, пока не закончится чек:
total = 0
while True:
price = input('Цена (пустая строка — конец): ')
if price == '':
break
total += int(price)
print('Итого:', total)
Здесь аккумулятор копит сумму, а пустая строка работает стоп-сигналом — два приёма этого урока в одной программе. Подробно про break и while True — в тринадцатом уроке, а поведение while с условием — в пятом.
| Задача | Старт | Шаг внутри цикла |
|---|---|---|
| Сумма | total = 0 | total += x |
| Счётчик событий | count = 0 | count += 1 внутри if |
| Максимум | best = первый элемент | if x > best: best = x |
| Минимум | worst = первый элемент | if x < worst: worst = x |
Сначала предскажи ответ в голове — это главный навык программиста.
total = 0
for n in [5, 10, 15]:
total += n
print(total)
count = 0
for w in ['кот', 'барсук', 'уж']:
if len(w) <= 3:
count += 1
print(count)
total = 0
for p in [50, 25]:
total = 1
total += p
print(total)
1. Где объявляют аккумулятор?
2. Чему равносильно total += x?
3. С чего правильно начинать поиск максимума в списке?
4. Чем счётчик отличается от суммы-аккумулятора?
5. Что вернёт sum([2, 3, 4])?
6. Как посчитать среднее арифметическое за один проход по списку?
7. С чего правильно начинать поиск и максимума, и минимума?
8. Что делает словарь-аккумулятор при подсчёте частот?
Для списка оценок grades = [4, 5, 3, 5, 4] посчитайте за один проход сумму через аккумулятор total и количество пятёрок через счётчик fives. Выведите обе величины одной строкой: print(total, fives).
Как посчитать сумму чисел в цикле Python?
Объявить total = 0 до цикла и внутри делать total += x; после цикла в total — сумма. Для простого случая без фильтров короче встроенная sum(list) — тот же цикл, свёрнутый в один вызов.
Урок 2: rangeПочему максимум нельзя искать от нуля?
На списке отрицательных чисел ни один элемент не превзойдёт ноль, и цикл вернёт фантомный ноль вместо настоящего максимума. Правильный старт — первый элемент списка: он гарантирует, что чемпион — настоящее число из данных.
Зачем писать аккумулятор руками, если есть sum()?
Ручной цикл нужен, когда условий больше: отобрать перед накоплением (continue или if), посчитать несколько величин за один проход, найти максимум по своему правилу. sum, max и min закрывают базовые случаи одной строкой.
Как посчитать среднее арифметическое в цикле?
Двумя аккумуляторами за один проход: total += x и count += 1, после цикла total / count. Так не приходится дважды перебирать список — сумма и количество копятся параллельно. Пустой список проверьте заранее: деление на ноль никуда не денется.
Как посчитать, сколько раз встретилось каждое слово?
Словарём-аккумулятором: если ключа ещё нет — создаём его со значением 1, если есть — увеличиваем на единицу. Готовый аналог — collections.Counter из стандартной библиотеки.
Урок 3: for по словарюПочему average считают двумя аккумуляторами, а не через sum и len?
Чтобы перебрать данные один раз: total и count растут параллельно. Вариант sum(temps) / len(temps) даёт тот же ответ, но заставляет список обходить дважды. На больших данных разница в скорости заметна.
Понравился урок? Сошлитесь на него
«Счётчик — тот же аккумулятор, только шаг всегда единица.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Циклы · Урок 5
Цикл while в Python: повторять, пока условие
while повторяет тело, пока условие верно: число шагов заранее неизвестно. Разбираем проверку условия, шаг к выходу и главный риск — бесконечный цикл.
Циклы · Урок 7
Оператор continue в Python: пропуск итерации
continue пропускает остаток тела для текущего элемента и переходит к следующему: не выход из цикла, а фильтр в потоке. Сравниваем с break на одних данных.
Циклы · Урок 13
Бесконечный цикл while True в Python
Цикл, который сам не кончается, а останавливается по событию: меню, игра-угадайка, поток задач. while True плюс break — главный цикл интерфейсов и игр.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Словари · Урок 11
Counter: словарь, который считает сам
Counter из collections — словарь, который считает сам: слова строки, буквы слова, повторения в списке. most_common отдаёт самых частых, арифметика счётчиков сравнивает две выборки.
посчитать количество повторений pythonсчётчик словарь python
json · Урок 10
Обход данных: циклы по JSON-спискам
for по списку словарей, извлечение полей, суммирование выручки и list comprehension — превращаем выгрузку заказов в отчёт.
python цикл по jsonpython перебрать json список
Циклы · Урок 18
Числа в цикле Python: суммы, факториалы, Фибоначчи
Сумма, факториал и Фибоначчи — три классические задачи на один каркас: аккумулятор со стартовым значением и цикл, который шаг за шагом вносит вклад.
python сумма чисел цикломфакториал python цикл