Работа с подмножествами данных: срезы в Python

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

Основы работы со срезами списков

Срезы (slice) позволяют извлекать, копировать и изменять подмножества элементов из списка. Основной синтаксис: список[начало:конец:шаг]. Все параметры необязательны и имеют значения по умолчанию: начало = 0, конец = длина списка, шаг = 1. Важно помнить, что элемент с индексом конец не включается в результат.

Базовое использование среза:


numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sublist = numbers[2:7]  # индексы с 2 (включительно) до 7 (исключительно)
print(sublist)  # [2, 3, 4, 5, 6]

Python list element (получение элемента списка в python)

[2, 3, 4, 5, 6]

Python add to list (добавление элемента в список)

Здесь start=2, stop=7. В результате получены элементы с индексами 2,3,4,5,6. Если указать только start (numbers[2:]) - получим элементы от индекса 2 до конца. Если только stop (numbers[:5]) - от начала до 5 (не включая 5). Отрицательные индексы отсчитываются от конца списка: numbers[-3:] возвращает последние три элемента.

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


first_three = numbers[:3]
print(first_three)  # [0, 1, 2]

Python copy list (копирование списка в python)

[0, 1, 2]

Python list extend (метод extend для списка)

Параметр start опущен, поэтому срез берётся от начала списка.

Проблема: если N больше длины списка, срез вернёт весь список без ошибки. Например, numbers[:20] даст [0,1,...,9]. Это не всегда ожидаемо, если требуется строго N элементов. Следует проверять длину списка или использовать islice из модуля itertools для строгого ограничения.

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


last_three = numbers[-3:]  # последние 3 элемента
print(last_three)  # [7, 8, 9]

Python list reverse (реверс списка в python)

[7, 8, 9]

Python empty list (создание пустого списка)

Используется отрицательный индекс для start. Параметр stop опущен - до конца списка.

Проблема: если указать start меньше чем -len(list) (например, numbers[-15:]), то срез начнётся с начала списка. Это может быть неочевидно. Аналогично, stop за пределами списка игнорируется.

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


every_second = numbers[::2]
print(every_second)  # [0, 2, 4, 6, 8]

Python list slice (срезы списков в python)

[0, 2, 4, 6, 8]

Python filter list (фильтрация списка с помощью filter)

Параметр step=2 выбирает элементы с шагом 2. Отрицательный шаг позволяет идти в обратном направлении.

Проблема: при использовании шага, отличного от 1, легко получить пустой список, если диапазон не содержит ни одного элемента (например, numbers[5:2:1] - пусто, так как start > stop при положительном шаге).

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


reversed_list = numbers[::-1]
print(reversed_list)  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Python list function (функции для работы со списками)

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Python добавить элемент в массив (добавление элемента в конец списка (append) в python)

Шаг -1 заставляет срез идти от конца к началу. Это простой способ реверсирования списка.

Проблема: создаётся новый список, что может быть неэффективно для больших списков. Для реверсирования на месте следует использовать метод list.reverse().

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


copy_list = numbers[:]
print(copy_list)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

элемент двумерного массива python (доступ к элементу двумерного массива (списка списков) в python)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python обратиться к элементу списка (обращение к элементу списка по индексу в python)

Полный срез от начала до конца создаёт поверхностную копию списка. Это эквивалентно list(numbers) или numbers.copy().

Проблема: копия является поверхностной - если список содержит изменяемые объекты (например, вложенные списки), их копии не создаются. Изменение во вложенном объекте отразится и в оригинале, и в копии. Для глубокого копирования используйте copy.deepcopy().

Как заменить часть списка другим списком?


numbers = [0,1,2,3,4,5,6,7,8,9]
numbers[2:5] = [100, 200, 300]
print(numbers)  # [0, 1, 100, 200, 300, 5, 6, 7, 8, 9]

как заменить элемент в списке python (замена элемента в списке по индексу (list[2] = new_value) в python)

[0, 1, 100, 200, 300, 5, 6, 7, 8, 9]

Присваивание срезу заменяет указанный диапазон элементов. Длина заменяемого диапазона может не совпадать с длиной вставляемого списка - список изменится по длине.

Проблема: при присвоении срезу можно случайно изменить размер списка, что приведёт к ошибкам в коде, рассчитывающем на фиксированное количество элементов. Также можно вставить пустой список ([]) для удаления участка, или наоборот, расширить список.

- Python максимальный элемент массива (поиск максимального элемента в списке с помощью max в python)
- Python одинаковые элементы списков (поиск одинаковых (повторяющихся) элементов в списках python)
- Find elements python (поиск элементов в списке по условию (list comprehension, filter) в python)

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

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

Удаление участка списка с помощью del

Пример

numbers = [10,20,30,40,50,60,70]
del numbers[2:5]  # удаляем элементы с индекса 2 по 4 (30,40,50)
print(numbers)  # [10, 20, 60, 70]
[10, 20, 60, 70]

Оператор del со срезом удаляет указанный диапазон элементов. Это модифицирует исходный список.

Вставка элементов в список через присвоение пустому срезу

Пример

numbers = [1,2,5,6]
numbers[2:2] = [3,4]  # вставляем элементы начиная с индекса 2, не удаляя существующие
print(numbers)  # [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]

Если указать одинаковые start и stop, срез пуст, и присваивание вставляет новый список.

Замена участка с перераспределением длины

Пример

numbers = [0,1,2,3,4,5]
numbers[1:4] = [10,20]  # заменяем 3 элемента (1,2,3) на 2 элемента (10,20)
print(numbers)  # [0, 10, 20, 4, 5]
[0, 10, 20, 4, 5]

Длина списка уменьшилась на 1. Аналогично можно увеличить длину, вставив больше элементов.

Использование переменных в качестве индексов среза

Пример

numbers = list(range(20))
start = 5
stop = 15
step = 3
result = numbers[start:stop:step]
print(result)  # [5, 8, 11, 14]
[5, 8, 11, 14]

Параметры среза могут быть вычислены заранее или переданы как аргументы. Это удобно при динамическом формировании срезов.

Срезы для строк (аналогично спискам)

Пример

text = "Python slicing"
sub = text[7:14]  # "slicing"
print(sub)  # slicing
slicing

Строки поддерживают те же операции срезов, что и списки, возвращая новую строку.

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

Пример

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

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

Срез с шагом -1 даёт перевёрнутую строку. Сравнение с оригиналом определяет палиндром.

Извлечение подсписка из вложенного списка

Пример

matrix = [[1,2,3], [4,5,6], [7,8,9]]
row_slice = matrix[1][0:2]  # вторая строка, первые два элемента
print(row_slice)  # [4, 5]
[4, 5]

Сначала обращаемся к строке по индексу, затем применяем срез к этой строке.

Срез с отрицательным шагом и отрицательными start/stop

Пример

numbers = [0,1,2,3,4,5,6,7,8,9]
# элементы с индексами 7,6,5,4,3 (идём от индекса 8 (не вкл) до 3 (вкл) с шагом -2)
result = numbers[-2:-9:-2]
print(result)  # [8, 6, 4]
[8, 6, 4]

Понимание направления: при отрицательном шаге start должен быть больше stop, иначе срез будет пуст.

Разбиение списка на части равной длины (chunking)

Пример

numbers = list(range(12))
chunk_size = 3
chunks = [numbers[i:i+chunk_size] for i in range(0, len(numbers), chunk_size)]
print(chunks)  # [[0,1,2], [3,4,5], [6,7,8], [9,10,11]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

Генератор списков со срезом - удобный способ разделить список на фрагменты.

Поверхностное копирование многомерного списка (внимание!)

Пример

original = [[1,2], [3,4]]
copy = original[:]  # поверхностная копия
copy[0][0] = 99
print(original)  # [[99,2], [3,4]]  - изменилось!
[[99, 2], [3, 4]]

Из-за того, что вложенные списки не копируются, изменение в копии затронуло оригинал. Для глубокого копирования используйте copy.deepcopy(original).

Использование среза для создания нового списка с преобразованием (через генератор)

Пример

numbers = [1,2,3,4,5]
# удвоить каждый элемент в срезе [1:4]
squared_slice = [x*2 for x in numbers[1:4]]
print(squared_slice)  # [4, 6, 8]
[4, 6, 8]

Срезы списков в Python - comments

En
Python list slice (python)