Удаление части элементов списка по срезу
В результате произойдет удаление элементов последовательности sequence от индекса i до индекса j . Операция удаления элементов среза последовательности эквивалентна выполнению sequence[i:j] = [] .
Больше об индексации среза читайте в операции получения среза последовательности и смотрите встроенную функцию slice()
Замечания по операции удаления среза последовательности:
Если индекс j указанного среза выходит за пределы индексации последовательности sequence — j > len(sequence) , то в результате операции произойдет удаление элементов от индекса i последовательности до ее конца.
Если оба индекса указанного среза i > len(sequence) и j > len(sequence) — выходят за пределы индексов последовательности, то в результате операции удаления, последовательность sequence не изменится.
Если индексы указанного среза i и j опущены, то в результате произойдет удаление всей последовательности.
Примеры удаления части элементов списка срезом.
>>> x = [1, 4, 7, 10, 13, 16, 19] >>> del x[1:4] >>> x # [1, 13, 16, 19] # индекс j выходит за пределы последовательности >>> x = [1, 4, 7, 10, 13, 16, 19] >>> del x[5:20] >>> x # [1, 4, 7, 10, 13] # Cрез выходит за пределы последовательности >>> del x[20:] >>> x # [1, 4, 7, 10, 13] # Индексы опущены >>> del x[:] >>> x # [] # Вложенные последовательности >>> x = [[1, 4, 7, 10], [13, 16, 19]] >>> del x[0][1:4] >>> x # [[1], [13, 16, 19]]
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Изменение/замена элемента списка по индексу
- Изменение части списка операцией среза
- Изменение списка срезом c заданным шагом
- Удаление части списка операцией среза
- Удаление части списка по срезу с заданным шагом
- Метод list.append(), добавляет значение в конец списка
- Метод list.clear(), очищает список
- Метод list.copy(), копия списка
- Метод list.extend(), расширяет список другой последовательностью
- Расширение списка его содержимым
- Метод list.insert(), вставить элемент по индексу
- Метод list.pop(), получение с удалением элемент списка
- Метод list.remove(), удаление элемента списка по значению
- Метод list.reverse(), разворачивает элементы списка
- Удаление элемента списка по индексу
- Удаление дубликатов из списка Python с сохранением очередности
Удаление элементов списка через срез
Удаляю элементы путем присвоения срезу пустого списка. Все работает. Но стоит задать шаг среза и выскакивает ошибка. В чем дело?
>>> a = [1, 2, 3, 4, 5, 6, 7, 8] >>> a[0:3] = [] >>> a [4, 5, 6, 7, 8] >>> a[0:4:2] = [] ValueError: attempt to assign sequence of size 0 to extended slice of size 2
Отслеживать
задан 16 апр 2017 в 9:41
81 1 1 серебряный знак 5 5 бронзовых знаков
А зачем удалять таким образом?
16 апр 2017 в 9:44
Почему не использовать del a[0:3]; , del a[0:4:2] ?
16 апр 2017 в 9:50
@YozhEzhi, по-моему стОит оформить ваш коментарий как ответ.
16 апр 2017 в 9:52
связанный вопрос: Как удалить каждый N-ый элемент из списка?
16 апр 2017 в 9:57
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Можно использовать инструкцию del :
>>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.25, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.25, 1234.5] >>> del a[:] >>> a []
Отслеживать
ответ дан 16 апр 2017 в 9:55
759 4 4 серебряных знака 16 16 бронзовых знаков
Я знаю разные способы удаления элементов списка, спасибо.)) Вопрос был в другом. Почему не работает вторая конструкция?
16 апр 2017 в 9:58
@bitt-boy, почитайте здесь
16 апр 2017 в 10:06
спасибо, понятно теперь, что это не баг, а фича)
16 апр 2017 в 10:22
Данная конструкция не работает, потому что вы берёте срез и на его место хотите поместить пустой список, а пайтон ждёт от вас список размерности среза. Об этом вам сообщает ошибка: ValueError: attempt to assign sequence of size 0 to extended slice of size 2
a[0:4:2] = [[], []] # [[], 2, [], 4, 5, 6, 7, 8] a[::2] = [[], [], [], []] # [[], 2, [], 4, [], 6, [], 8]]
Почему запись вида a = [] то есть запись без применения шага не выдаёт ошибок?
Дело в том, что в данном случае после = мы указываем новую ссылку для массива — [] . То есть ссылку на пустой массив. И делая такую запись, мы просто заменяем ссылку у переменной a с текущего непустого массива на пустой. А срез [start:end:step] — это массив ссылок на элементы массива, и для того чтобы заменить ссылки в нём на какие-либо другие, то нам, естественно, нужен массив такой же размерности, как и срез.
a[::2] = [None for x in range(len(a[::2]))] # [None, 2, None, 4, None, 6, None, 8]
Отслеживать
ответ дан 16 апр 2017 в 10:16
user243273 user243273
почему тогда без шага все работает?
16 апр 2017 в 10:36
@bitt-boy потому что без шага вы просто изменяете ссылку у переменной, а с шагом нужно изменять ссылки на элементы массива
– user243273
16 апр 2017 в 10:40
Непонятно, как срез a[2:4] при присвоении пустого массива заменяет ссылку у переменной a.
16 апр 2017 в 16:37
@bitt-boy просто эта операция a[2:4] = [] эквивалентна операции удаления del a[2:4] , а эта a[::2] = [] — нет. Считайте это особенностью языка и помните про его правила, особенно про главное: Явное лучше, чем неявное. И удаляйте элементы через операцию del , а не так, как вы делаете в этом вопросе.
– user243273
16 апр 2017 в 16:40
а почему тогда операция a[2:4:2] = [] не эквивалентна del a[2:4:2]?
16 апр 2017 в 16:44
Автор задал прекрасный вопрос на понимания механизмов реализации срезов в Пайтон -» а почему тогда операция a[2:4:2] = [ ] не эквивалентна del a[2:4:2]? » А какой результат вернет операция a[2:4:2] = [None] и почему ?
Вот такая запись «. = А[2:4:2]» возвращает ссылку на элемент А[3]. Вот такая запись -«. del a[2:4:2]», перед выполнением оператора «del», тоже вернет ссылку на элемент А[3]. Потому что, все, что расположено справа от оператора «=» — возвращает ССЫЛКИ НА ОБЪЕКТЫ. А все, что расположено слева от оператора «=» — возвращает не ссылки, но МЕСТО (Область) РАЗМЕЩЕНИЯ ссылок (их еще именами переменных называют).
Запись «А[2:4] = . » эквивалентна записи «А[2:4:1] = . » и определяет область, куда будет записана ссылка на объект, расположенный справа оператора «=». Для односвязных областей (таких как А[2:4] и А[2:4:1] — когда все элементы среза ближайшие соседи) внутренний механизм Итератора не запускается и область готова принять ссылку на произвольный объект класса СПИСОК (список с любым количеством итерируемых элементов), и, даже, не итерируемый список вида [ ] ( [ ] = [Nan], значение NaN не имеет ссылки, в отличие от значения None) .
Многосвязные области вида А[2:7:2], где элементы среза не ближайшие соседи, запускают механизм внутреннего Итератора, и справа от «=» для области «А[2:7:2] = . » необходимо поставить в соответствие итерируемый объект класса Список с тремя элементами для итерирования (реализуется механизм обычного множественного присваивания). Далее все очевидно.
Перефразируя выражение из одного культового фильма — «Итераторы — они повсюду!, Ну, или почти.»
Удалить последний элемент из списка Python
В этом посте мы обсудим, как удалить последний элемент из списка в Python.
1. Использование list.pop() функция
Самый простой подход — использовать список pop([i]) функция, которая удаляет элемент, присутствующий в указанной позиции в списке. Если мы не укажем никакого индекса, pop() удаляет и возвращает последний элемент в списке.
if __name__ == ‘__main__’ :
l = list ( range ( 1 , 5 ) )
print ( l ) # [1, 2, 3, 4]
print ( l ) # [1, 2, 3]
The pop([i]) функция вызывает IndexError если список пуст, поскольку он пытается выскочить из пустого списка.
2. Использование нарезки
Мы знаем, что списки в Python можно нарезать. Мы можем использовать нарезку, чтобы удалить последний элемент из списка. Идея состоит в том, чтобы получить подсписок, содержащий все элементы списка, кроме последнего. Поскольку операция среза возвращает новый список, мы должны присвоить новый список исходному списку. Это можно сделать с помощью выражения l = l[:-1] , куда l это ваш список. l[:-1] сокращение от l[0:len(l)-1] .
Списки — коротко!
Со списками, так же как и со строками, можно делать срезы. А именно:
A[i:j] срез из j-i элементов A[i] , A[i+1] , . A[j-1] .
A[i:j:-1] срез из i-j элементов A[i] , A[i-1] , . A[j+1] (то есть меняется порядок элементов).
A[i:j:k] срез с шагом k : A[i] , A[i+k] , A[i+2*k] . . Если значение k
Каждое из чисел i или j может отсутствовать, что означает “начало строки” или “конец строки”
Списки, в отличии от строк, являются изменяемыми объектами: можно отдельному элементу списка присвоить новое значение. Но можно менять и целиком срезы. Например:
A = [1, 2, 3, 4, 5] A[2:4] = [7, 8, 9]
Получится список, у которого вместо двух элементов среза A[2:4] вставлен новый список уже из трех элементов. Теперь список стал равен [1, 2, 7, 8, 9, 5] .
A = [1, 2, 3, 4, 5, 6, 7] A[::-2] = [10, 20, 30, 40]
Получится список [40, 2, 30, 4, 20, 6, 10] . Здесь A[::-2] — это список из элементов A[-1] , A[-3] , A[-5] , A[-7] , которым присваиваются значения 10, 20, 30, 40 соответственно.
Если не непрерывному срезу (то есть срезу с шагом k , отличному от 1), присвоить новое значение, то количество элементов в старом и новом срезе обязательно должно совпадать, в противном случае произойдет ошибка ValueError .
Обратите внимание, A[i] — это элемент списка, а не срез!
Операции со списками
Со списками можно легко делать много разных операций.
| x in A | Проверить, содержится ли элемент в списке. Возвращает True или False |
| x not in A | То же самое, что not(x in A) |
| min(A) | Наименьший элемент списка. Элементы списка могут быть числами или строками, для строк сравнение элементов проводится в лексикографическом порядке. |
| max(A) | Наибольший элемент списка |
| sum(A) | Сумма элементов списка, элементы обязательно должны быть числами |
| A.index(x) | Индекс первого вхождения элемента x в список, при его отсутствии генерирует исключение ValueError |
| A.count(x) | Количество вхождений элемента x в список |
| A.append(x) | Добавить в конец списка A элемент x . |
| A.insert(i, x) | Вставить в список A элемент x на позицию с индексом i . Элементы списка A , которые до вставки имели индексы i и больше сдвигаются вправо. |
| A.extend(B) | Добавить в конец списка A содержимое списка B . |
| A.pop() | Удалить из списка последний элемент, возвращается значение удаленного элемента |
| A.pop(i) | Удалить из списка элемент с индексом i , возвращается значение удаленного элемента. Все элементы, стоящие правее удаленного, сдвигаются влево. |
Упражнения
Большинство упражнений этого листка копирует задачи листка про списки. Но в предыдущем листке задачи необходимо решать без использования срезов, дополнительных списков, методов списков.
В этом же листке, наоборот, нельзя использовать циклы. Используйте срезы и методы.
Для многих упражнений написано, какое наибольшее число строк может быть в программе. Как правило, ограничения будут или в одну строку, или в три строки.
Если программа решается в одну строку, то необходимо использовать функции внутри функций. Например, вот так можно вычислить сумму всех чисел, введенных в строку, используя стандартную функцию sum :
print(sum(map(int, input().split())))
Обратите внимание, в однострочном решении нельзя сохранять список в переменной — нужно сразу же его обработать и вывести результат.
Решение в две строки строки, как правило, должно иметь следующий вид:
A = input().split() print(' '.join(. ))
При этом зачастую не требуется преобразовывать элементы списка к типу int .
Решение в три строки строки, как правило, должно иметь следующий вид:
A = input().split() A = . print(' '.join(. ))
A: Четные индексы
Решите эту задачу в одну строку
1 2 3 4 5
1 3 5
G: Наибольший элемент
Решите эту задачу в две строки
1 2 3 2 1
M: Вывести в обратном порядке
Решите эту задачу в одну строку
1 2 3 4 5
5 4 3 2 1
O: Переставить соседние
Решите эту задачу в три строки
1 2 3 4 5
2 1 4 3 5
Q: Циклический сдвиг вправо
Решите эту задачу в две строки
1 2 3 4 5
5 1 2 3 4
R: Кузнечики
Решите эту задачу в четыре строки
1 2 3 4 2
2
4 1 2 2 3
Y: Числа k-боначчи
Решите эту задачу в пять строк
