Slicing в Python: извлечение и модификация данных

Раздел: Основы Python -> Работа со строками и списками

Основной синтаксис срезов

Срезы в Python позволяют извлекать подпоследовательности из строк, списков, кортежей и других последовательностей. Формат: sequence[start:stop:step]. Индексы start и stop указывают границы (stop не включается), step задает шаг.


s = "Hello, World!"
print(s[0:5])   # 'Hello'
print(s[7:12])  # 'World'

срезы python (срезы в python)

Hello
World

Для списков работает аналогично:


lst = [0, 1, 2, 3, 4, 5]
print(lst[1:4])  # [1, 2, 3]
[1, 2, 3]
Типичные ошибки: Путаница с тем, что stop не включается. Если указать stop больше длины, ошибки не будет, срез вернет все до конца. Если start больше stop, результат пустой.

Как получить последние символы или элементы?

Использование отрицательных индексов. Отрицательные индексы отсчитываются с конца: -1 - последний элемент, -2 - предпоследний и т.д.


text = "Python"
print(text[-3:])   # 'hon'
hon

lst = [10, 20, 30, 40]
print(lst[-2:])    # [30, 40]
[30, 40]
Возможные проблемы: При отрицательном stop, если stop равен 0, срез пустой, так как stop не включается. Например, lst[:-0] - это то же, что lst[:0] - пустой список.

Как извлечь элементы с определённым шагом?

Параметр step задает шаг. Если step > 1, выбираются каждый step-й элемент. Если step отрицательный, движение идет в обратном направлении.


word = "abcdef"
print(word[::2])   # 'ace'
print(word[::-1])  # 'fedcba'
ace
fedcba

Для списков:


nums = [1,2,3,4,5]
print(nums[::-1])  # [5,4,3,2,1]
[5, 4, 3, 2, 1]
Типичная ошибка: Step = 0 вызывает ValueError: slice step cannot be zero. При отрицательном step start и stop тоже должны быть указаны с учетом обратного порядка, иначе результат может быть пустым.

Как сохранить срез для многократного использования?

Встроенный объект slice. Можно создать объект среза и применять его к разным последовательностям.


my_slice = slice(1, 5, 2)
s = "abcdefghi"
print(s[my_slice])       # 'bd'
lst = [10,20,30,40,50,60]
print(lst[my_slice])     # [20, 40]
bd
[20, 40]
Нюансы: Объект slice сам по себе не проверяет границы; ошибки возникают только при индексировании. Удобно для передачи среза как аргумента в функцию.

Как изменить часть списка с помощью среза?

Присваивание срезу заменяет указанный диапазон элементов. Можно также удалять (присвоить пустой список) или вставлять (заменить на большее количество элементов).


lst = [0, 1, 2, 3, 4, 5]
lst[1:3] = [10, 20]   # замена
print(lst)             # [0, 10, 20, 3, 4, 5]
[0, 10, 20, 3, 4, 5]

Удаление:


lst = [0, 1, 2, 3, 4, 5]
lst[1:4] = []
print(lst)             # [0, 4, 5]
[0, 4, 5]
Ошибки: Если присвоить срезу строку, а не список, будет ошибка TypeError. Также нельзя присваивать срезу строку, если сам объект - список. Присвоение срезу с шагом требует, чтобы количество заменяемых элементов совпадало с длиной присваиваемой последовательности.

Как создать независимую копию списка?

Полный срез [:] создает неглубокую копию списка. Изменения копии не затрагивают оригинал (для вложенных объектов копируются ссылки).


original = [1, 2, 3]
copy = original[:]
copy[0] = 100
print(original)  # [1, 2, 3]
print(copy)      # [100, 2, 3]
[1, 2, 3]
[100, 2, 3]
Предостережение: Для списков с вложенными изменяемыми объектами (например, список списков) [:] не делает глубокую копию. Вложенные элементы остаются общими.

Расширенные примеры срезов

Здесь приведены менее очевидные применения срезов в Python.

Замена символа в строке через срезы

Строки неизменяемы, поэтому единственный способ «заменить» символ - создать новую строку, объединив части до и после.

Пример

s = "Hello"
index = 1
new_char = "a"
s_new = s[:index] + new_char + s[index+1:]
print(s_new)  # "Hallo"
Hallo

Этот метод работает для любой позиции. Если нужно заменить несколько символов, можно использовать срез шире.

Циклический сдвиг списка

Сдвинуть элементы списка вправо или влево на k позиций.

Пример

lst = [1,2,3,4,5]
k = 2
# сдвиг влево
left_shifted = lst[k:] + lst[:k]
print(left_shifted)  # [3,4,5,1,2]

# сдвиг вправо
right_shifted = lst[-k:] + lst[:-k]
print(right_shifted) # [4,5,1,2,3]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]

Работает для строк аналогично, только результатом будет строка.

Проверка палиндрома с помощью среза

Сравнение строки с её обратной версией - простой способ проверки.

Пример

def is_palindrome(s):
    return s == s[::-1]

print(is_palindrome("radar"))   # True
print(is_palindrome("hello"))   # False
True
False

Для строк с пробелами и знаками препинания можно предварительно отфильтровать.

Удаление элементов с заданным шагом

Оператор del позволяет удалить срез, в том числе с шагом. Например, удалить каждый второй элемент списка.

Пример

lst = [0,1,2,3,4,5,6]
del lst[::2]
print(lst)  # [1,3,5]
[1, 3, 5]

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

Извлечение столбца из списка списков (матрицы)

Для двумерного списка можно получить столбец, используя генератор списка и срез по индексу строки. Но срез самого столбца невозможен напрямую, однако можно срезать каждую строку.

Пример

matrix = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
]
# Получить второй столбец (индекс 1)
col = [row[1] for row in matrix]
print(col)  # [2,5,8]

# Срезом можно получить подматрицу: первые две строки, столбцы 1-2
sub = [row[1:3] for row in matrix[:2]]
print(sub)  # [[2,3],[5,6]]
[2, 5, 8]
[[2, 3], [5, 6]]

Здесь срезы применяются как к внешнему списку (для выбора строк), так и к каждой строке (для выбора столбцов).

Срезы в Python - comments

En
срезы python (python)