Если у вас стоит задача итерироваться по последовательности чисел, то на помощь придёт удобная функция range(), которую предоставляет Python. Она позволяет генерировать арифметические прогрессии.
Рассмотрим простейший пример использования функции range():
if __name__ == '__main__':
for i in range(5):
print(f'Текущее число i = {i}')
Результатом выполнения будет вывод на консоль:
Текущее число i = 0
Текущее число i = 1
Текущее число i = 2
Текущее число i = 3
Текущее число i = 4
Заметьте, что первым значением будет 0, а последним 4. Передаваемое в функцию range() конечное значение (в нашем случае это 5) никогда не является частью генерируемой последовательности, это важно запомнить.
Есть возможность начать последовательность не с 0, а с какого-то другого значения. Давайте попробуем это сделать и чуть изменим наш скрипт:
if __name__ == '__main__':
for i in range(2, 5):
print(f'Текущее число i = {i}')
В этом случае в консоль выведется:
Текущее число i = 2
Текущее число i = 3
Текущее число i = 4
Т.е. когда мы указываем начальное значение для функции range(), оно учитывается, в отличие от конечного.
Ещё одной особенностью функции range() является то, что ей можно передать третий параметр - шаг (его ещё называют инкремент, как Вам больше нравится). Он может даже принимать отрицательные значения, если это диктуется логикой Вашей Python программы. Посмотрим, как это работает:
if __name__ == '__main__':
for i in range(1, 11, 2):
print(f'Текущее число i = {i}')
В данном случае мы указали в качестве шага 2, поэтому на экране отобразится:
Текущее число i = 1
Текущее число i = 3
Текущее число i = 5
Текущее число i = 7
Текущее число i = 9
Пару моментов по вышеприведённому выводу на консоль: ещё раз обращаем внимание на то, что начальное значение для функции range() учитывается, далее для последующих элементов последовательности будет применяться операция прибавления значения шага. Снова видим, что конечный элемент последовательности 11 исключён из вывода на консоль.
В случае отрицательного значения шага всё работает аналогично:
if __name__ == '__main__':
for i in range(11, 1, -2):
print(f'Текущее число i = {i}')
Результат в консоли:
Текущее число i = 11
Текущее число i = 9
Текущее число i = 7
Текущее число i = 5
Текущее число i = 3
Если угодно, можно использовать вообще отрицательные значения для начального, конечного элементов и самого шага:
if __name__ == '__main__':
for i in range(-1, -20, -5):
print(f'Текущее число i = {i}')
Вывод на консоль:
Текущее число i = -1
Текущее число i = -6
Текущее число i = -11
Текущее число i = -16
Как видите, принципиально ничего не изменилось, все те же правила, о которых мы говорили выше, применяются и в этом случае.
Для перебора индексов последовательности очень удобно сочетать функции range() и len(), как показано в примере ниже:
if __name__ == '__main__':
my_list = ['Это', 'элементы', 'простого', 'списка', 'на', 'Python']
for i in range(len(my_list)):
print(f'Значение элемента списка с индексом {i}: {my_list[i]}')
Результат выполнения этого скрипта на консоли:
Значение элемента списка с индексом 0: Это
Значение элемента списка с индексом 1: элементы
Значение элемента списка с индексом 2: простого
Значение элемента списка с индексом 3: списка
Значение элемента списка с индексом 4: на
Значение элемента списка с индексом 5: Python
Как видите, в этом случае мы последовательно переберём все индексы элементов списка, что позволяет обратиться к самим элементам по индексу и вывести на экран. Отметим, правда, что в большинстве случаев гораздо удобнее использовать функцию enumerate() для этой задачи.
Если просто распечатать результат вызова функции range() на экран, то происходит странная вещь:
if __name__ == '__main__':
print(range(1, 100))
На экране отобразится:
range(1, 100)
Всё это из-за того, что во многих случаях объект, возвращаемый функцией range() ведёт себя как список, но по факту таковым не является. Это объект, который возвращает элементы желаемой последовательности, когда мы по ней "бежим", но в действительности не происходит создание списка, таким образом сохраняется место в памяти. Этот объект называют итерабельным (англ. iterable), то есть подходящим для функций и конструкций Python, которые ожидают нечто, из чего можно получать последовательно элементы, пока они не закончатся. Мы уже видели пример такой конструкции в Python в другой статье, посвящённой циклу for, а вот, ниже, пример функции sum(), которая также умеет работать с итерабельными объектами и вычисляет их сумму:
if __name__ == '__main__':
print(sum(range(5))) # 0 + 1 + 2 + 3 + 4 = 10
По комментарию в самом скрипте можно догадаться, что на консоль в этом случае будет выведено значение 10.
На этом пока всё, мы познакомились с функцией range() в Python, попробуйте начать использовать её в Ваших скриптах, если пока этого не делали, и обязательно поделитесь в комментариях своим опытом. Удачи!
Примеры из этой статьи: https://github.com/AllineedRu/PythonExamples/blob/main/ain_range/__init__.py