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

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

  • автор:

Python: как удалить / удалить каждый n-й элемент из списка?

Я уже просмотрел этот пост: Python: создание нового списка из существующих отбрасывая каждый n-й элемент, но по какой-то причине он не работает для меня:

Эта функция принимает список и n . Затем он удаляет каждый n-й элемент, используя n-шаг из списка, и печатает результат.

Вот мой вызов функции:

Неверный вывод:
[2, 4] вместо [1, 3]

Тогда я попробовал вариант по ссылке выше:

Опять же, вызов функции:

Дает мне тот же неправильный результат: [2, 4] вместо [1, 3]

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

5 ответов

В вашей первой функции mylist[0::n] равен [1, 3] , потому что 0::n означает, что первый элемент равен 0, а остальные элементы — это каждый n th элемент после первого. Как сказал Даниэль, вы можете использовать mylist[::n] , что означает каждый n th элемент.

В вашей второй функции индекс начинается с 0, а 0 % 0 равен 0, поэтому он не копирует первый элемент. То же самое для третьего элемента ( 2 % 2 равен 0). Так что все, что вам нужно сделать, это new_list = [item for index, item in enumerate(mylist) if (index + 1) % n != 0]

Совет: вы можете использовать return вместо print() в подобных функциях.

Еще один способ сделать это — создать новый список, содержащий только те элементы, которые вам нужны.

Если бы n было 5, это вернуло бы список, содержащий элементы [1,2,3,4,6,7,8,9,11 . ] Преимущество этого состоит в том, что вы сохраняете свой первоначальный список, который полезно, если вы собираетесь повторно использовать данные. Однако, если вы беспокоитесь о сохранении памяти, то, вероятно, не самый лучший.

Ваш первый подход выглядит хорошо для меня — вам просто нужно адаптировать свой стартовый индекс, если вы хотите отбросить элементы 1, 1 + n, 1 + 2n, . (как кажется, имеет место):

Вывод правильный, вы удаляете элементы с индексами 0, n, 2n, . Таким образом, 1 и 3 удаляются, 2 и 4 остаются. Поэтому, если вы хотите напечатать элемент 0, n, 2n, . просто напишите

Как в списке обнулить каждый второй элемент при помощи цикла for в Python

Нужно написать два цикла for, один из которых обнулит каждый второй элемент списка (передать диапазон нужно с помощью функций range() и len() и использовать срезы). Второй цикл for должен просуммировать оставшиеся элементы, записав получившееся значение в переменную. Мой код

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

Используя range. Можно задать шаг третьим параметром. Пример:

Соотвественно сделать это подобным образом (перепроверьте и отладьте код пожалуйста)

P.S Если Вы считаете сумму, лучше не обнулять элемент, а вырезать его. Например используя функцию pop()

Python-сообщество

Есть необходимость удалять, к примеру, каждый 4-й элемент в списке до тех пор, пока len() этого списка не будет равно 1.
Пример.
Есть список
Из него нужно удалять каждый 4-й элемент. После удаления элемента продолжаем отсчитывать дальше 4-ый элемент.
1) — удалили первый элемент
2) — после удаления “4” продолжаем отсчет с элемента “5”.
3) — далее выполняются аналогичные действия
4)
5) — остался один элемент. len(spisok) == 1 и программа завершает работу.
Не знаю, как сделать так, чтобы после удаления элемента продолжать отсчет со следующего элемента, а не с начала списка.

Списки в Python

Как и строки, списки в языке Python относятся к упорядоченным последовательностям. Однако в отличие от строк, списки являются изменяемыми объектами и могут содержать значения любых типов: уже известные нам числа и строки, сами списки, а также объекты любого другого типа данных. При этом изменяться списки могут непосредственно без всяких дополнительных манипуляций и фокусов. Сделать это можно как при помощи операций присваивания по индексам и срезам, так и при помощи методов типа или специальной инструкции удаления del . По сути списки являются самым гибким типом упорядоченных коллекций в Python , реализуя практически все необходимое для создания и обработки структур данных любой степени сложности. Итак.

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

Создание списков в Python

Проще всего литерал списка в Python создается при помощи квадратных скобок, внутри которых элементы списка перечисляются через запятую (см. пример №1 ). В случае необходимости последний элемент списка можно также завершать запятой. Это никак не повлияет на количество элементов списка, а значит и его длину.

Пример №1. Создание списков в Python (часть 1).

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

Создать список можно также при помощи встроенного конструктора типа list() . Если использовать его без аргумента, то он вернет нам пустой список. Если же передать ему итерируемый объект, например, строку или кортеж, то конструктор вернет список, элементами которого будут соответствующие элементы переданного объекта (см. пример №2 ).

Пример №2. Создание списков в Python (часть 2).

Но и это еще не все. В Python для создания списков могут использоваться специальные генераторы списков, которые применяют выражение к каждому элементу передаваемого итерируемого объекта и на основе их вычисления возвращают новый список (см. пример №3 ).

Пример №3. Создание списков в Python (часть 3).

Таким образом, в простейшем случае для генерации списка нужно в квадратных скобках написать выражение, которое будет применяться к каждому элементу передаваемого итерируемого объекта, и через пробел прописать соответствующий заголовок цикла for без завершающего двоеточия. Но это в простейшем случае. Полный синтаксис генераторов мы рассмотрим в отдельном параграфе позже.

Стоит заметить, что любой генератор списка можно реализовать через цикл for . Более того, в сложных случаях именно так и следует поступать. Но в простейших случаях генераторы списка интуитивно понятнее, работают чуть быстрее цикла for и занимают чуть меньше места по объему кода.

Доступ по индексу и срезы списков

Операции доступа по индексу и получения срезов для списков имеют практически тот же самый синтаксис и смысл, что и для строк (см. пример №4 ).

Пример №4. Доступ к элементам списка по индексу (часть 1).

Однако в отличие от строк списки являются изменяемыми последо­ватель­ностями. Поэтому в результате обращения к элементу списка по его индексу возвращается некоторый объект, расположенный по указанному смещению. А поскольку таким объектом может оказаться не только строка, но и любой другой объект, то для получения доступа к элементам на более глубоком уровне вложенности может потребоваться целая цепочка из нескольких индексов (см. пример №5 ).

Пример №5. Доступ к элементам списка по индексу (часть 2).

Следует добавить, что цепочка доступа к конкретному элементу может иметь и более сложную конструкцию, включающую не только квадратные скобки с индексами для доступа к элементам списков, но и квадратные скобки с ключами для доступа к элементам словарей, и точки для доступа к атрибутам объектов. Например, для списка li = [<'one': 'top', 'two': ['abc', [4, 5]]>, 0.3] цепочка получения доступа ко второму элементу вложенного списка [4, 5] будет иметь вид li[0][‘two’][1][1] .

Что касается получения срезов для списков, то в результате операции всегда возвращается новый список, состоящий из указанных в срезе элементов исходного списка (см. пример №6 ). Сам же исходный список не изменяется до тех пор, пока мы не присвоим срезу новое значение (см. примеры №8 и №9 ).

Пример №6. Операция взятия среза у списков.

При извлечении срезов следует помнить, что нумерация элементов в списках начинается с нуля, а элемент с индексом второго предела, указанного в квадратных скобках, не будет присутствовать в срезе. Например, в срезе списка li_1[0:7] будут присутствовать первые семь элементов с индексами от 0 до 6 , но не включая элемент с индексом 7 .

Как и в случае со строками, один или оба предела среза можно опускать. Если не указывать первый предел, интерпретатор будет начинать срез с первого элемента списка (с индексом 0 ), а при отсутствии второго предела срез будет идти до конца списка. Если опустить оба предела, мы получим копию списка. Опять же, при необходимости разрешается указывать и третий предел, который будет задавать шаг среза (см. пример №7 ).

Пример №7. Порядок использования шага среза у списков.

Как видим, шаг среза также может иметь отрицательное значение (аналогично строкам). В этом случае отсчет элементов списка и шагов ведется в противоположном направлении, а границы среза указываются справа налево, т.е. индекс элемента, стоящего правее в списке должен указываться первым. Например, в срезе примера li_1[-3:1:-3] отсчет ведется справа налево, начиная с 3 -го элемента, отсчитываемого с конца списка, до элемента с индексом 1 , который находится левее и в срез не включается.

Изменяемость списков означает, что мы можем не только получать доступ к элементам списка, но также изменять их значения, вообще удалять или добавлять в список новые элементы. При этом изменению подвергается не копия списка, как в случае со строками, а непосредственно сам список. Так для изменения значения отдельного элемента списка нужно просто найти элемент в списке по индексу и присвоить ему новое значение (см. пример №8 ).

Пример №8. Изменение значений элементов списков.

В более сложных случаях, когда нужно удалить или добавить элементы, а также изменить значения сразу нескольких элементов, следует использовать срезы (см. пример №9 ).

Пример №9. Изменение списков при помощи срезов (часть 1).

Обратите внимание, что для удаления конкретного элемента списка нужно взять срез, включающий только этот элемент, и присвоить ему пустой список. Если же использовать просто индекс, элемент останется, а пустой список станет его значением (см. предыдущий пример №8 ). Кроме того, при использовании срезов присваиваться должны итерируемые объекты, например, списки, строки или кортежи. В противном случае интерпретатор выдаст ошибку.

При желании в срезах можно использовать и третий параметр, т.е. шаг среза. Но здесь нужно быть осторожным, т.к. количество элементов такого среза должно соответствовать количеству элементов в присваиваемом итерируемом объекте (см. пример №10 ).

Пример №10. Изменение списков при помощи срезов (часть 2).

Как видим, операции взятия среза у списков обладают внушительным арсеналом возможностей. Более того, при помощи этих возможностей вполне могут быть реализованы и некоторые методы класса list , которые мы рассмотрим чуть ниже.

Операторы списков в Python

Поскольку списки относятся к упорядоченным последовательностям, то операторы + , += , * и *= имеют для них практически тот же смысл, что и для строк (см. пример №11 ).

Пример №11. Использование операторов + и * применительно к спискам.

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

Что касается оператора проверки на вхождение in , то примени­тельно к спискам он совершает поиск требуемого объекта (левый операнд) среди элементов целевого списка (правый операнд). В случае успеха операция возвращает True , иначе – False (см. пример №12 ).

Пример №12. Использование оператора in применительно к спискам.

Напомним, что оператор in может использоваться не только самостоятельно, но и совместно с оператором отрицания not , который инверсирует возвращаемое логическое значение оператора in . Соответственно, например, операция ‘крот’ not in [‘кот’, ‘кит’] вернет True вместо False .

Если возникает необходимость в обходе элементов списка, то, по аналогии со строками, можно смело использовать оператор цикла for (см. пример №13 ).

Пример №13. Использование цикла for для обхода элементов списка.

Оператор идентичности is возвращает True , если оба операнда указывают на один и тот же объект в памяти компьютера. В противном случае операция возвращает False . Например, инструкция type(0.53) is float вернет True , т.к. вызов функции type(0.53) возвращает не что иное, как сам объект типа float . Добавим, что как и оператор проверки на вхождение in , оператор is может использоваться совместно с оператором отрицания not .

Еще одним полезным и универсальным оператором языка Python является оператор удаления del , который позволяет с легкостью удалять переменные, элементы по индексу или ключу, атрибуты объектов и т.д. Применительно к спискам мы можем использовать del для удаления всего списка, срезов или отдельных его элементов (см. пример №14 ).

Пример №14. Использование оператора del применительно к спискам.

На этом рассмотрение базовых операций над списками мы заканчиваем. Осталось рассмотреть методы класса list и встроенные функции, применимые к спискам.

Функции и методы списков в Python

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

  • li.count(x) – возвращает количество в списке li элементов с указанным значением x (см. пример №15 ). Отметим, что в отличие от аналогичного метода для строк, здесь указывать интервал для поиска нельзя, т.к. метод принимает только один аргумент.
  • li.index(x[, start[, end]]) – возвращает индекс i первого вхождения элемента li[i] со значением x в список li или в срез списка li[start:end] , если он задан. В случае неудачного поиска метод вызывает исключение ValueError . Обратите внимание, что при использовании среза отсчет индекса элемента все равно стартует с начала всего списка.

Пример №15. Методы списков (часть 1).

  • li.insert(i, x) – вставляет элемент со значением x в указанную позицию i . Тот же результат можно получить и при помощи инструкции li[i:i] = [x] (см. пример №16 ).
  • li.append(x) – добавляет элемент со значением x в конец списка li (тоже самое что и li[len(li):len(li)] = [x] ).
  • li.extend(iterable) – добавляет элементы из итерируемого объекта iterable в конец списка li (тоже самое что и li[len(li):len(li)] = iterable ). Не забываем, что итерируемыми являются, например, строки, списки, кортежи, но не числа.

Пример №16. Методы списков (часть 2).

  • li.remove(x) – удаляет из списка li первый попавшийся элемент, имеющий значение x . Если элемента с указанным значением в списке не окажется, будет вызвано исключение ValueError (см. пример №17 ).
  • li.pop([i]) – удаляет из списка li элемент с указанным индексом i , а затем возвращает его. Если индекс не указан (параметр необязательный), удаляется последний элемент списка, т.к. по умолчанию i принимается равным -1 .
  • li.clear() – удаляет все элементы из списка (тоже самое что и del li[:] ).

Пример №17. Методы списков (часть 3).

  • li.reverse() – изменяет порядок следования элементов в списке li на обратный. Получить тот же результат можно и с помощью инструкции li = li[::-1] (см. пример №18 ).
  • li.copy() – возвращает поверхностную копию списка li ( li[:] ).

Пример №18. Методы списков (часть 4).

  • li.sort(*, key=None, reverse=False) – сортирует элементы списка li . При сортировке используется обычная операция сравнения при помощи оператора < . Соответственно сортировать в одном списке числа и строки без манипуляций не получится. Если же нужно повлиять на алгоритм сортировки элементов списка, следует использовать собственную функцию сравнения, принимающую единственный аргумент и возвращающую значение, которое и будет использовано в операции сравнения. Объект функции нужно передать в качестве значения именованному аргументу key=my_func . Тогда при сортировке для каждого элемента списка будет вызываться переданная функция, а в сравнении будет участвовать не сам элемент, а результат вызова функции (см. пример №19 ). Кроме того, если использовать именованный аргумент reverse=True , сортировка будет производиться в обратном порядке.

Пример №19. Методы списков (часть 5).

Помимо собственных методов к спискам применим и ряд встроенных функций: min() (возвращает элемент с минимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), max() (возвращает элемент с максимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), sum() (возвращает сумму элементов списка, при этом элементы должны быть числами), len() (возвращает количество элементов в списке), sorted(iterable, *, key=None, reverse=False) (встроенная функция сортировки), filter(function, iterable) (фильтрация элементов списка) и т. д.

Краткие итоги параграфа

  • В Python списки представляют собой упорядоченные изменяемые коллекции объектов произвольного типа с доступом по индексу.
  • Чтобы создать список достаточно перечислить требуемые объекты (элементы списка) через запятую внутри квадратных скобок (например, li = [5.3, ‘слон’, 2] ). Доступ к элементу списка можно получить по его индексу, т.е. порядковому номеру элемента в списке. При этом следует помнить, что индексация элементов в списках начинается с нуля (например, инструкция print(li[0]) выведет первый элемент списка, т.е. число 5.3 ).
  • Также списки могут быть созданы при помощи конструктора list(iterable) (например, инструкция list(‘abc’) вернет список [‘a’, ‘b’, ‘c’] ) и генератора списков (например, [simb for simb in ‘abc’] вернет тот же список [‘a’, ‘b’, ‘c’] ).
  • Что касается срезов, то для списков они имеют практически тот же смысл, что и для строк. Однако здесь операция среза всегда возвращает новый список, состоящий из указанных в срезе элементов исходного списка. Сам же исходный список не изменяется до тех пор, пока мы не присвоим срезу новое значение.
  • Поскольку списки являются изменяемыми последовательностями, их можно изменять непосредственно: удалять элементы, добавлять новые, изменять значения уже существующих элементов. Например, пусть у нас есть список li = [1, 2, 3] . Тогда инструкция li[0:0] = [4] добавляет в начало списка новый элемент, li[0] = 5 изменяет значение первого элемента списка, а del li[1] удаляет второй элемент списка.
  • Применимы к спискам и знакомые нам арифметические операторы. Так оператор + используется для объединения списков (например, операция конкатенации [1, 2] + [3, 4] вернет список [1, 2, 3, 4] ), а комбинированный оператор += расширяет целевой список (левый операнд) за счет элементов присоединяемого в конец дополнительного списка, т.е. правого операнда (например, в результате выполнения инструкций li = [1, 2] и li += [3, 4] в переменной будет храниться список [1, 2, 3, 4] ). Что касается оператора умножения * и соответсвующего ему комбинированного оператора *= , то они расширяют список за счет дублирования имеющихся элементов указанное число раз (например, в результате выполнения инструкций li = [1, 2] и li *= 3 в переменной будет храниться список [1, 2, 1, 2, 1, 2] ).
  • К спискам применимы оператор in и цикл for . Первый проверяет наличие требуемого объекта среди элементов целевого списка, а второй позволяет поочередно обойти все элементы списка. Кроме того, поскольку списки относятся к изменяемым последовательностям, для них доступен еще и оператор удаления del , который позволяет удалять не только отдельные элементы списка, но также срезы и сам список целиком.
  • В конце мы познакомились с рядом методов типа list . Опять же, они дают нам возможность выполнять широкий спектр операций над списками, а для их использования не нужно импортировать никаких модулей, т.к. они уже встроены в сам интерпретатор. Однако не стоит забывать, что в отличие от строк, списки изменяемы, поэтому их методы в основном изменяют список непосредственно, а не возвращают его измененную копию. Найти методы списков можно в подразделе «Sequence Types – list, tuple, range» раздела «Built-in types» стандартной библиотеки.

Вопросы и задания для самоконтроля

1. Найдите неверное утверждение о списках: являются последовательностями, упорядоченные, неизменяемые. Показать решение.

Ответ. Списки относятся к изменяемым упорядоченным коллекциям объектов. Так что утверждение о том, что списки неизменяемы, ложно.

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

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

3. Какие из представленых литералов относятся к типу list : [‘зимний’, ‘летний’] , 5.0 , ‘[3, 4]’ , «Питон, Python» ? Проверьте типы программно. Показать решение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *