§8 Срезы

Отрицательный индекс

Ранее мы уже показали, что доступ к элементу последовательности можно получить обратившись по индексу и имени, например: L[0] – первый элемент, L[1] – второй и т. д. Последний элемент последовательности в которой содержится N элементов будет иметь индекс равный N - 1. Однако в Python можно использовать и отрицательную индексацию. Пусть дан список L (изображенный на рисунке). Тогда к последнему элементу можно обратиться так: L[-1] (или L[8]), к предпоследнему L[-2] и т. д. В итоге, первый элемент – L[-9], он же L[0].
srez1
Такое представление индекса очень удобно, если необходимо проводить некоторые операции с конца последовательности, в особенности, когда размер этой последовательности весьма велик. Отрицательный индекс также удобно применять в срезах.

Срезы

Срезы (slices) – операции над последовательностями в результате которых производится выборка определенных элементов массива с помощью индексов. Срезы можно получать для любой последовательности. Срезы заимствованы из языка программирования Fortran.
Синтаксис срезов:

L[start:stop:step]

где:
start – индекс начала среза (индексы могут быть отрицательными),
stop – индекс конца среза ([start, stop)),
step – шаг (может быть отрицательным).
start, stop и step могут быть только целыми числами или целочисленными переменными.
Срезы позволяют выполнять довольно сложные алгоритмы, запись которых выглядит очень компактно. Обычно срезы используются для создания новых последовательностей. Срезы можно использовать в различных операциях, например, конкатенации. Однако, срезы нельзя применять для изменения неизменяемых последовательностей таких, как строка. Если осуществляется попытка получить срез несуществующих элементов, то будет возвращен пустой список. Приведем примеры использования срезов на примере списка L:

L = [4, 31, 7, 12, 0, 8, 10, 3, 11, 3, 28, 16, 5, 9]

Срез L[:] будет означать выбор всего списка, тогда копию списка L можно создать так:

B = L[:]

Последняя операция будет аналогична такой:

B = list(L)

Примечание. Не путайте с операцией B = L, которая создаст новую ссылку на всё тот же список L!
Индекс stop не включается в срез!

print(L[1:5])

[31, 7, 12, 0]
Реверс массива можно сделать с помощью отрицательного шага:

print(L[::-1])

[9, 5, 16, 28, 3, 11, 3, 10, 8, 0, 12, 7, 31, 4]
Если шаг отрицателен, то выборка элементов будет выполняться с конца массива, т. е. справа налево.
Индексы start или stop можно опустить это будет означать, что срез выполняется от начала или до конца, соответственно.

print(L[:8])

[4, 31, 7, 12, 0, 8, 10, 3]

print(L[8:])

[11, 3, 28, 16, 5, 9]

print(L[-8:])

[10, 3, 11, 3, 28, 16, 5, 9]

print(L[:-8])

[4, 31, 7, 12, 0, 8]
Выполнение срезов с определенным шагом:

print(L[::2])

[4, 7, 0, 10, 11, 28, 5]

print(L[4:10:3])

[0, 3]

print(L[-10::5])

[0, 3]

print(L[-3:-10:-3])

[16, 11, 8]

Изменение списков с помощью срезов

С помощью срезов можно выполнять операции изменения как исходного среза, так и любых других. Приведем примеры срезов с конкатенацией:

A = [4, 31, 7, 12, 0, 8, 10]
B = [3, 11, 3, 28, 16, 5, 9]
L = A[2::2] + B[:2:-2]
print(L)

[7, 0, 10, 9, 16]
В следующей программе все элементы списка A, начиная со второго, будут заменены элементами списка B:

A = [4, 31, 7, 12, 0, 8, 10]
B = [3, 11, 3, 28, 16, 5, 9]
A[2:] = B
print(A)

[4, 31, 3, 11, 3, 28, 16, 5, 9]
Примечание. Если целевому списку (получаемого в виде среза) присвоить значения списка имеющего больший размер, то будет сгенерировано исключение ValueError. Например:

A = [4, 31, 7, 12, 0, 8, 10]
B = [3, 11, 3, 28, 16, 5, 9]
A[::3] = B[:]
Traceback (most recent call last):
  File "srez2.py", line 3, in 
    A[::3] = B[:]
ValueError: attempt to assign sequence of size 7 to extended slice of size 3

С помощью операции del и срезов можно удалять в списках произвольные элементы.

A = [4, 31, 7, 12, 0, 8, 10]
B = [3, 11, 3, 28, 16, 5, 9]
del A[::2]
del B[-1:-5:-1]
print(A)
print(B)

[31, 12, 8]
[3, 11, 3]

Print Friendly, PDF & Email

Comments are closed.