Распространенный вариант использования циклов со списками — агрегация. Агрегацией называются любые вычисления, которые строятся на основе всего набора данных: например, поиск максимального значения, среднего, суммы и так далее. Процесс агрегации не требует от программиста знания нового синтаксиса, но влияет на алгоритм решения задач. Поэтому имеет смысл рассмотреть его отдельно. Начнем с поиска максимального значения:
def calculate_max(coll):
# Если коллекция пустая, то у нее не может быть максимального значения
# В подобных ситуациях принято возвращать None
# Это классический пример использования идиомы guard expression
if coll == []:
return None
# Сравнение элементов начинаем с первого элемента
max = coll[0]
# Обход начинаем со второго элемента
for i in range(1, len(coll)):
current = coll[i]
# Если текущий элемент больше максимального,
# то он становится максимальным
if current > max:
max = current
# Не забываем вернуть максимальное число
return max
print(calculate_max([])) # => None
print(calculate_max([3, 2, -10, 38, 0])) #=> 38
В этом примере агрегации мы видим вычисление. Оно включает в себя сравнение всех элементов для поиска одного, которое станет результатом этой операции.
Обратите внимание, что начальным значением max
взят первый элемент, а не 0
или любое другое число. Ведь может оказаться так, что все числа в списке меньше 0
, и тогда мы получим неверный ответ.
Нейтральный элемент
Теперь рассмотрим поиск суммы:
def calculate_sum(coll):
# Начальное значение суммы
sum = 0
for i in range(len(coll)):
# Поочередно складываем все элементы
sum += coll[i]
return sum
# Сумма элементов всегда возвращает какое-то число
# Если список пустой, то сумма его элементов равна нулю
print(calculate_sum([])) # => 0
print(calculate_sum([3, 2, -10, 38, 0])) # => 33
# Процесс вычислений
sum = 0
sum = sum + 3 # 3
sum = sum + 2 # 5
sum = sum + -10 # -5
sum = sum + 38 # 33
sum = sum + 0 # 33
Алгоритм поиска суммы значительно проще, но обладает парой важных нюансов.
Чему равна сумма элементов пустого списка? С точки зрения математики такая сумма равна 0
, что совпадает со здравым смыслом. Если у нас нет яблок, значит у нас есть 0
яблок. Другими словами, количество яблок равно нулю. Функции в программировании работают по такой же логике.
Второй момент связан с начальным элементом суммы. У переменной sum
есть начальное значение равное 0
. Зачем вообще задавать значение? Любая повторяющаяся операция начинается с какого-то значения. Нельзя просто так объявить переменную и начать с ней работать внутри цикла. Это приведет к неверному результату:
# В Python мы не можем создать переменную не задав какое-то значение
# В качестве "отсутствия значения" используем None
sum = None
# Первая итерация цикла
sum = sum + 2
В результате такого вызова внутри будет ошибка TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
. Она возникает из-за попытки сложить 2
и None
. Значит какое-то значение все же нужно. В коде выше выбран 0
, потому что все остальные варианты приведут к неверному результату. Если начальное значение будет равно 1
, то результат получится на единицу больше, чем нужно.
В математике существует понятие нейтральный элемент бинарной операции — это элемент, который ничего не меняет в результате его использования. Другими словами, сложение любого числа с нулем всегда дает это же число. Тогда любую сумму, например 3 + 2 + 8
, можно вычислить как 0 + 3 + 2 + 8
, чем мы и пользуемся в нашем коде.
Нейтральный элемент – это важная часть любой агрегирующей операции. Именно с него начинается сам процесс агрегации. В случае сложения – это 0, в случае умножения – 1. Даже у конкатенации есть нейтральный элемент – это пустая строка: '' + 'one'
будет 'one'
.
Агрегация далеко не всегда означает, что коллекция элементов сводится к некоторому простому значению. Результатом агрегации может быть даже сложная структура — например, список. Подобные примеры часто встречаются в реальной жизни. Самый простой пример – это список уникальных слов в тексте.
Выводы
Агрегация — это вычисления на основе всего набора данных, такие как поиск максимального значения, среднего, суммы и т.д.
При агрегации может использоваться нейтральный элемент. Он не изменяет результат операции. Нейтральный элемент операции сложения — это 0. Для умножения — 1. Для конкатенации строк: пустая строка ''
.
Результатом агрегации может быть не только простое значение, но и сложная структура, например, список уникальных слов в тексте.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.