Питонистический подход к циклам for: range() и enumerate()

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Автор заметки, перевод которой мы сегодня публикуем, хочет рассказать о некоторых особенностях использования циклов for в Python.



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

Если вы занялись разработкой на Python, имея опыт работы с другим популярным языком программирования, вроде PHP или JavaScript, то вам знакома методика применения переменной-счётчика, хранящей, например, индекс текущего элемента массива, обрабатываемого в цикле. Вот пример работы с циклом, написанный на JavaScript:

let scores = [54,67,48,99,27];
for(const i=0; i < scores.length; i++) {
   console.log(i, scores[i]);
}
/*
0 54
1 67
2 48
3 99
4 27
*/

Работая с циклами for очень важно понимать то, что эти циклы не перебирают массивы. Они лишь дают программисту механизм для работы с переменной-счётчиком, которая используется для обращения к элементам обрабатываемых массивов.

В предыдущем примере переменная i не имеет какого-то явного отношения к массиву scores. Она всего лишь хранит некое число, которое увеличивается на 1 в каждой итерации цикла, и которое, как оказывается, подходит для последовательного обращения к элементам массива по их индексам.

Старый (неудачный) способ работы с массивами


В Python нет традиционных циклов for, подобных тому, что показан выше. Правда, если вы похожи на меня, то первым вашим желанием при освоении Python станет поиск способа создания цикла, с которым вам привычно и удобно работать.

В результате вы можете обнаружить функцию range() и написать на Python нечто подобное следующему:

scores = [54,67,48,99,27]
for i in range(len(scores)):
   print(i, scores[i])
"""
0 54
1 67
2 48
3 99
4 27
"""

Проблема этого цикла заключается в том, что он не очень хорошо соответствует идеологии Python. В нём мы не перебираем список, а, вместо этого, используем вспомогательную переменную i для обращения к элементам списка.

На самом деле, даже в JavaScript существуют методы, позволяющие перебирать массивы, так сказать, без посредников. Речь идёт о циклах forEach и for of.

Использование функции enumerate()


Если вам нужно адекватным образом отслеживать «индекс элемента» в for-цикле Python, то для этого может подойти функция enumerate(), которая позволяет «пересчитать» итерируемый объект. Её можно использовать не только для обработки списков, но и для работы с другими типами данных — со строками, кортежами, словарями.

Эта функция принимает два аргумента: итерируемый объект и необязательное начальное значение счётчика.

Если начальное значение счётчика enumerate() не передаётся — оно, по умолчанию, устанавливается в 0. Функция создаёт объект, генерирующий кортежи, состоящие из индекса элемента и самого этого элемента.

scores = [54,67,48,99,27]
for i, score in enumerate(scores):
   print(i, score)

Такой код получился гораздо чище кода из предыдущего примера. Мы ушли от работы со списком индексов, мы перебираем сами значения, получая к ним прямой доступ в цикле for, и видим значения, с которыми работаем, в объявлении цикла.

Вот одна приятная возможность, которая понравится тем, кому нужно выводить нумерованные списки так, чтобы номер первого элемента был бы не 0, в соответствии с его индексом, а 1. Обычно для того, чтобы это сделать, приходится менять выводимый номер элемента. Например — так: i + 1. При использовании же функции enumerate() достаточно передать ей, в качестве второго аргумента, то число, с которого нужно начинать нумерацию. В нашем случае — 1:

scores = [54,67,48,99,27]
for i, score in enumerate(scores, 1):
   print(i, score)
"""
1 54
2 67
3 48
4 99
5 27
"""

Итоги


Надеюсь, этот небольшой рассказ о циклах for в Python позволил вам узнать что-то новое об этом языке.

Уважаемые читатели! Знаете ли вы ещё какие-нибудь способы применения функции enumerate()? Кажутся ли вам циклы, построенные с использованием enumerate(), более читабельными, чем циклы, созданные с использованием range(len())?

Источник: https://habr.com/ru/company/ruvds/blog/485648/


Интересные статьи

Интересные статьи

Когда мы в конце прошлого года перерабатывали свой курс по Deep Learning, чтобы сделать его более наглядным и ориентированным на кейсы из реальной бизнес-практики, мы вкл...
Мне было необходимо делать 2 раза в сутки бэкап сайта на «1С-Битрикс: Управление сайтом» (файлов и базы mysql) и хранить историю изменений за 90 дней. Сайт расположен на VDS под уп...
Приступая к животрепещущей теме резервного копирования на «Битрикс», прежде всего хотелось бы поблагодарить разработчиков, реализовавших автоматическое резервное копирование в облачное хранилище в вер...
Мы продолжаем публиковать разборы задач, которые предлагались на недавнем чемпионате. На очереди — задачи, взятые из квалификационного раунда для специалистов по машинному обучению. Это трети...
Короткая история о fio и etcd Производительность кластера etcd во многом зависит от производительности его хранилища. etcd экспортирует некоторые метрики в Prometheus, чтобы предоставить нужны...