Статьи

Учебные материалы по языку Python — от основ до продвинутых тем

range и slice

Страница 29 из 34 · 2026-10-26 · 3 мин чтения

range

range — неизменяемая последовательность целых чисел, которая вычисляет элементы по требованию и не хранит их в памяти:

print(list(range(5)))print(list(range(2, 8)))print(list(range(10, 0, -3)))print(list(range(0)))

Форма range(stop), range(start, stop) или range(start, stop, step). Конечное значение не включается, step не может быть нулём.

Операции

range поддерживает те же операции, что и неизменяемые последовательности:

r = range(0, 100, 5)print(len(r))print(r[3])print(r[-1])print(r[2:5])print(15 in r)print(16 in r)print(r.index(25))print(r.count(25))print(r.start, r.stop, r.step)

Проверка x in range(...) выполняется за O(1) даже для огромных диапазонов:

print(10 ** 15 in range(10 ** 18))

Методы и атрибуты range

ЭлементОписание
start, stop, stepПараметры диапазона
index(x)Позиция значения, иначе ValueError
count(x)0 или 1

Сравнение

print(range(3) == range(0, 3, 1))print(range(0) == range(5, 5))print(range(0, 5, 2) == range(0, 6, 2))

Диапазоны сравниваются как последовательности значений.

Типичные применения

for i in range(3):    print(i)for i in range(len("abc") - 1, -1, -1):    print(i)evens = list(range(0, 11, 2))print(evens)print(sum(range(1, 101)))

Для перебора элементов вместе с индексами предпочитайте enumerate, а не range(len(...)).

slice

Срез a[1:5:2] — это синтаксический сахар для объекта slice:

s = slice(1, 5, 2)data = list(range(10))print(data[s])print(data[1:5:2])print(s.start, s.stop, s.step)

Объекты slice удобно хранить в переменных и переиспользовать:

FIRST_THREE = slice(None, 3)EVERY_SECOND = slice(None, None, 2)print("abcdefg"[FIRST_THREE])print([1, 2, 3, 4, 5][EVERY_SECOND])

Метод slice.indices

s = slice(None, 100)print(s.indices(5))print(s.indices(10))

Возвращает кортеж (start, stop, step) с учётом длины последовательности.

Правила срезов

  • Конечный индекс не включается
  • Отрицательные индексы считаются с конца
  • Выход за границы не вызывает ошибку, срез просто усекается
  • Отрицательный шаг идёт в обратную сторону
s = "abcdef"print(s[2:])print(s[:-1])print(s[-3:])print(s[1:100])print(s[::-1])print(s[4:1:-1])

Результаты: cdef, abcde, def, bcdef, fedcba, edc.

Срезы и изменяемые последовательности

a = [0, 1, 2, 3, 4, 5]a[1:3] = [10, 20, 30]print(a)del a[::2]print(a)a[:0] = [-1, -2]print(a)

Присваивание срезу заменяет участок последовательностью другой длины. Для расширенных срезов (с шагом) длина должна совпадать.

Поддержка в своих классах

Для поддержки срезов реализуйте __getitem__, принимающий int или slice:

class Squares:    def __init__(self, n):        self.n = n    def __len__(self):        return self.n    def __getitem__(self, index):        if isinstance(index, slice):            return [self[i] for i in range(*index.indices(self.n))]        if index < 0:            index += self.n        if not 0 <= index < self.n:            raise IndexError(index)        return index ** 2sq = Squares(10)print(sq[3])print(sq[2:6])print(sq[::3])

Задания

  1. Выведите числа от 100 до 1 с шагом 7 и вычислите их сумму без цикла.
  2. Реализуйте класс-последовательность, поддерживающую срезы и отрицательные индексы.
  3. Разбейте список на блоки по n элементов через срезы и range.