slice(stop) slice(start, stop) slice(start, stop, step)
start
- тип int
, начальный индекс среза;stop
- тип int
, конечный индекс среза (не будет входить в конечный результат);step
- тип int
, шаг, с которым нужно выбирать элементы.Изменено в Python 3.12: объекты
slice()
теперь доступны для хэширования, что позволяет использовать их в качестве ключейdict
и элементовset
. (Авторы: Уилл Брэдшоу, Фуркан Ондер и Рэймонд Хеттингер.)
Иногда требуется получить из последовательности не один элемент, а сразу несколько или элементы по некоторой закономерности. Для этого существуют срезы. Надо отметить, что изначальная последовательность никак не меняется, объект slice()
создает копию.
Класс slice()
вернет объект, представляющий срез/часть последовательности, которая будет следовать шаблону, указанному в аргументах. Возвращаемый объект среза представляет новый набор индексов начальной последовательности, заданных диапазоном start
, stop
, step
, как в range()
.
sequence[slice(x, y, z)] # эквивалентно вызову sequence[x, y, z]
Срезы удобнее создать при помощи расширенного синтаксиса индексации, квадратных скобок []
с двоеточиями в качестве разделителей внутри. Например: x[start:stop:step]
или x[start:stop]
x[a:b]
срез от a
до b-1
элементов x[a], x[a+1], …, x[b-1]
.x[a:b:-1]
срез от b
до a+1
элементов x[b], x[b-1], …, x[a+1]
, то есть меняется порядок элементов.x[a:b:k]
срез с шагом k
: x[a], x[a+k], x[a+2*k],…
. Если значение k < 0
, то элементы идут в противоположном порядке.a
или b
может отсутствовать, что означает “начало последовательности” или “конец последовательности”Использование itertools.islice()
позволяет получить срез у итератора или генератора.
Также читайте Подробное руководство по индексам и срезам в Python.
[:stop:step]
- начинаем с самого края коллекции, то есть с первого элемента (включая его), если шаг положительный или с последнего (включая его), если шаг отрицательный (и соответственно перебор идет от конца к началу).[start:: step]
- идем до самого края коллекции, то есть до последнего элемента (включая его), если шаг положительный или до первого элемента (включая его), если шаг отрицательный (и соответственно перебор идет от конца к началу).step = 1
, то есть последовательный перебор слева направо указывать не обязательно - это значение шага по умолчанию. В таком случае достаточно указать [start:stop]
Можно сделать даже так [:]
- это значит взять коллекцию целикомВажно: При срезе, первый индекс входит в выборку, а второй нет!
То есть от start
включительно, до stop
, где stop
не включается в результат. Поэтому, например, sequence[::-1]
не идентично sequence[:0:-1]
, так как в первом случае мы включим все элементы, а во втором дойдем до индекса sequence[0]
, но не включим его!
slice.indices()
.Каждый объект slice()
в Python имеет метод .indices
. Этот метод возвращает кортеж (start, end, step)
, с помощью которой можно построить цикл, эквивалентный операции среза. Звучит сложно? Разбираемся:
>>> sequence = list("Python")
Затем создадим объект slice()
. Например возьмем каждый второй элемент, т.е. sequence[::2]
.
# эквивалентно `[::2]` >>> my_slice = slice(None, None, 2)
Так как в качестве некоторых аргументов используется None
, то объект slice()
должен вычислять фактические значения индекса на основе длины последовательности. Следовательно, чтобы получить кортеж фактических индексов (без None
), необходимо передать длину последовательности методу slice.indices()
, например:
>>> indices = my_slice.indices(len(sequence)) >>> indices # (0, 6, 2)
Теперь можно воссоздать цикл следующим образом:
sequence = list("Python") start, stop, step = (0, 6, 2) i = start while i != stop: print(sequence[i]) i = i+step
slice()
.>>> line = 'срезы' >>> y = slice(0, 3) >>> line[y] # сре # что эквивалентно использованию # расширенного синтаксиса индексации >>> line[0:3] # сре ############## # Еще примеры ############## >>> lst = list(range(10)) >>> lst # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> i = slice(2,5,2) >>> lst[i] # [2, 4] >>> i = slice(2) >>> lst[i] # [0, 1] >>> i = slice(2, 3) >>> lst[i] # [2] >>> i = slice(-3) >>> lst[i] # [0, 1, 2, 3, 4, 5, 6] >>> i = slice(None, 5, -1) >>> lst[i] # [9, 8, 7, 6] >>> i = slice(-2,5,-1) >>> lst[i] # [8, 7, 6] >>> i = slice(0, None, 2) >>> lst[i] # [0, 2, 4, 6, 8] >>> i = slice(-1, None, -2) >>> lst[i] # [9, 7, 5, 3, 1] >>> i = slice(None, None, -1) >>> lst[i] # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
С помощью объекта среза slice()
или расширенного синтаксиса индексации можно создавать копии списков, для последующего изменения, не боясь, что изменится оригинал.
>>> x = [0, 1, 2, 3] >>> y = x[::] >>> y[0] = 10 >>> x, y # [0, 1, 2, 3], [10, 1, 2, 3]
Можно развернуть список или строку, только это будет копия оригинала.
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> y = x[::-1] >>> x, y # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] >>> x = 'кукарача' >>> y = x[::-1] >>> print(x, y, sep=' <---> ') # кукарача <---> ачаракук
Срезом, так же можно изменить список, но не строку или кортеж, т. к. они неизменяемы.
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> x[3:7] = [0, 0, 0, 0] >>> x # [1, 2, 3, 0, 0, 0, 0, 8, 9, 10]