Числовой диапазон (range) в Python

Range в Python: как работает, функции, генерация и индексация

Числовой диапазон (range) — упорядоченная последовательность целых чисел с заданным шагом.

Синтаксис функции range выглядит так:

range([start], stop[, step])

start — число начала последовательности (по умолчанию 0).
stop — число конца последовательности.
step — шаг между каждым числом последовательности.

Параметры start и step — не обязательные, если их не указывать, то последовательность будет создаваться от 0 до stop с шагом 1.

Также следует помнить, что:

  • Все параметры функции range должны быть целыми числами.
  • Параметры могут быть отрицательными числами.
  • Если шаг step отрицательный, нужно помнить, что значение start должно быть больше значения stop.
  • Параметр stop не включается в последовательность.

Генерация списка с помощью range

Для генерации будем использовать различные комбинации:

my_list = list(range(10))
print(my_list)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
my_list = list(range(5, 10))
print(my_list)
#[5, 6, 7, 8, 9]
my_list = list(range(5, 10, 2))
print(my_list)
#[5, 7, 9]
my_list = list(range(0, -10, -1))
print(my_list)
#[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

Генерация списка в цикле с помощью range

nums = [n for n in range(1, 11)]
print(nums)
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Использование числового диапазона range в циклах

Несколько простых примеров:

for i in range(5):
    print(i)
#0
#1
#2
#3
#4
for i in range(5, 10):
    print(i)
#5
#6
#7
#8
#9
for i in range(2, 10, 2):
    print(i)
#2
#4
#6
#8

Функция range для обратного порядка:

for i in range(-2, -10, -2):
    print(i)
#-2
#-4
#-6
#-8

Индексация и срезы в range

Индексация range

Тут все стандартно, как и в списках и в кортежах, индексация начинается 0.

Обращение к элементу диапазона:

data = range(1, 10)
print(data[0])
print(data[5])
print(data[-1])
#1
#6
#9

Срезы в range

Синтаксис срезов [I:J:Step].
С I до смещения J, не включая его.

data = range(1, 10)
print(data[1:4])
print(data[:4])
print(data[3:])
#range(2, 5)
#range(1, 5)
#range(4, 10)

Основные операции с числовым диапазоном range

Длина диапазона: len(r)

data = range(10)
print(len(data))
#10

Минимальный элемент диапазона: min(r)

data = range(10)
print(min(data))
#0

Максимальный элемент диапазона: max(r)

data = range(10)
print(max(data))
#9

Индекс числа в диапазоне: range.index(x[, start[, end]])
Необязательные аргументы start и end, указывают на промежуток поиска:

data = range(10)
print(data.index(5))
#5
data = range(2, 10)
print(data.index(5))
#3

Примеры работы range в задачах

Найти сумму чисел от 1 до 10.

Создадим переменную s, в которую будем записывать сумму чисел. И присвоим ей значение 0.
Создадим числовой диапазон от 1 до 11 (т.к. range не включает последнее число в последовательность)
Создадим цикл for в котором будем перебирать в диапазоне цифры от 1 до 10.
Внутри цикла будем записывать в переменную s сумму с каждым числом из диапазона.

s = 0
for i in range(1, 11):
    s = s + i
print(s)
#55

Найти сумму четных чисел от 1 до 10.

Делаем, все тоже самое, что и в первой задаче, но в range делаем начало диапазона 0 и шаг 2, таким образом, получаем все четные числа от 0 до 10.

s = 0
for i in range(0, 11, 2):
    s = s + i
print(s)
#30

Вывести все буквы строки отдельно.

Создаем цикл длина диапазона, которого равна длине строки.
С помощью индексации выводим каждый элемент строки в цикле.

s = 'abcdef'
    for i in range(len(s)):
    print(s[i])
#a
#b
#c
#d
#e
#f

Частая ошибка index out of range

Это ошибка возникает довольно часто, если не внимательно относиться к границам диапазона.

Допустим, есть список чисел от 1 до 10, нужно оставить в этом списке только числа, которые делятся на 2.

nums = [n for n in range(1, 11)]   #генерируем список с числами о 1 до 10
for i in range(len(nums)):         #перебераем все числа
    if nums[i] % 2 != 0:               #находим числа, которые не делятся на 2
        del nums[i]                        #удаляем такие числа
print(nums)
#builtins.IndexError: list assignment index out of range

В итоге вместо результата, получаем ошибку.

Это случилось из-за того, что мы прямо в цикле удалили элемент из списка, тем самым изменив его длину, а это повлияло на диапазон.
Т.е. на старте цикла была одна длина списка с числами, а во время выполнения эта длина изменилась. Python, держа в памяти старую длину, пробует обратиться по индексам к тем элементам, которых уже нет в списке.

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

nums = [n for n in range(1, 11)]   #генерируем список с числами о 1 до 10
fin_nums = []                      #создаем пустой список
for i in range(len(nums)):         #перебираем все числа
    if nums[i] % 2 == 0:               #находим числа, которые делятся на 2
        fin_nums.append(nums[i])           #добавляем в наш новый список
print(fin_nums)
#[2, 4, 6, 8, 10]

Теперь все гуд.

Содержание: