Рубрики
Без рубрики

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

Встроенная структура данных Python встроенная структура данных имеет много мощных методов, с которыми любой продвинутый программист Python должен быть знаком. Однако некоторые операции в списках не могут быть выполнены, просто вызывая правильный метод. Вы можете добавить один элемент в список, используя метод добавления (элемент) в списке. Если вы хотите добавить список … Самый питонический способ удалить несколько элементов из списка Подробнее »

Автор оригинала: Lukas.

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

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

То же самое касается, если вы хотите удалить элемент из списка, вы просто называете метод Убрать предмет) И вы получаете желаемый результат.

Но, вы когда-нибудь задавались вопросом, как удалить список предметов из данного списка? Или что, если были даны индексы предметов, которые будут удалены, как бы вы сделали это?

Это были вопросы, которые я просил себя в одном из моих последних проектов хобби. Поэтому я решил узнать самый питонический способ сделать это.

Проблема

Давайте отставьте нашу проблему, подобную этой: учитывая список задач, Как мы можем удалить все предметы из списка которые отмечены как сделанные?

В настоящее время реализация выглядит следующим образом:

class Task:
    def __init__(self, title):
        self.title = title
        self.done = False
        self.done_by = None
        
    def is_done(self):
        return self.done
    
    def set_done(self, name):
        self.done = True
        self.done_by = name
    
    def __repr__(self):
        state = f'was done by {self.done_by}' if self.done else 'is not done'
        s = f'Task: {self.title} {state}'
        return s
    
    
todo_list = [
    Task('Clean House'),
    Task('Walk Dog'),
    Task('Buy Bread'),
    Task('Repair Car'),
    Task('Plant Tree'),
    Task('Water Flowers'),
    Task('Bake Cake')
]


todo_list[0].set_done('Bob')
todo_list[2].set_done('Alice')
todo_list[5].set_done('Bob')

# print the whole list
print(todo_list)

Итак, как мы можем очистить наш список Todo, чтобы он содержит только задачи, которые еще не были сделаны?

Растворы

Следующие решения могут быть разделены на две группы:

  1. Удалить элементы данных индексов
  2. Удалить элементы определенным условием

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

indices = []
for idx, task in enumerate(todo_list):
    if task.is_done():
        indices.append(idx)

Так как требуется одна итерация списка, чтобы найти индексы, это добавляет На) к сложности выполнения. Тем не менее, так как любое решение имеет как минимум временную сложность На) мы можем пренебрегать этим первым шагом.

Метод 1: Удалите один элемент из списка и повторите в цикле

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

Поэтому одним решением удаления нескольких элементов является использование метода, который удаляет один элемент и выполняет его в цикле. Хотя есть ловушка к этому решению. После того, как мы удалим элемент на индексе 0, все другие элементы смены, и их индексы меняются, потому что элемент при индексе 1 теперь находится на индексе 0 и так далее.

Вот как решение будет выглядеть как код:

1.1. Удалить с помощью POP ()

list.pop () Метод Удаляет и возвращает последний элемент из существующего Список Отказ list.pop (индекс) Способ с дополнительным аргументом индекс Удаляет и возвращает элемент в положение показатель Отказ

indices = [0, 2, 5] # must be ordered!
shift = 0
for i in indices:
    todo_list.pop(i-shift)
    shift += 1

Ну, наверное, это выглядит немного неловко для вас, и будьте уверены, это не так, как вы сделаете это в Python!

Чтобы избежать смещения, мы можем обратить вспять список индексов, чтобы мы могли удалить элементы с конца для начала:

indices = [0, 2, 5]
for i in sorted(indices, reverse=True):
    todo_list.pop(i)

1.2. Удалить с помощью удаления ()

Слегка проще прощественное решение, но все еще не лучшее решение, использует Метод Re . Переместить (предмет) Отказ

Мы повторяем перечень и проверяем каждый элемент, если он удовлетворил условие, чтобы его можно было удалить. Это решение будет выглядеть так:

for task in todo_list:
    if task.is_done():
        todo_list.remove(task)

Будьте осторожны, если вы используете Убрать предмет) В списке простых типов данных, таких как целые числа. Функция Удалить () Удаляет первое вхождение данного значения из списка!

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

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

1.3. Удалить используя itemgetter () и удалить ()

Если вы используете функцию itemgetter из модуля оператор Есть еще одно интересное решение, которое в основном является улучшением раствора 1.1.

Функция itemgetter принимает произвольное количество показателей и возвращает все элементы из этих показателей в кортеже. Вот реализация предлагаемого решения:

from operator import itemgetter

indices = [0, 2, 5]
for item in (itemgetter(*idx)(todo_list)):
    xs.remove(item)

Но все же, код более сложным, чем он должен быть.

Метод 2. Удалить несколько предметов из списка

В предыдущих решениях мы просто адаптировали функциональность для удаления одного элемента, чтобы мы могли использовать его внутри цикла. В этом разделе мы посмотрим на большее количество решений для Pythonic для этой проблемы.

2.1. Удалите все элементы из списка

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

2.2. Удалить ломтик из списка

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

Это может выглядеть так:

del todo_list[1::2]

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

2.3. Удалите случайно распределенные элементы из списка с использованием заданных операций

Во-первых, мы повторяем перечень один раз и извлеките все предметы для удаления. Затем мы конвертируем оба списка для устанавливаемых и выполнения удаления с использованием заданных операций. Это выглядит следующим образом:

done = []
for task in todo_list:
    if task.is_done():
        done.append(task)
        
todo_list = list(set(todo_list) - set(done))

Под капотом набор в Python является HASHMAP, который позволяет выполнять определенные операции на множествах очень быстро ( o (1) ). К сожалению, мы должны Конвертировать из списка в комплект и назад Так что мы потеряем преимущество в скорости. И снова мы в конечном итоге с O (n) решение.

Дополнительная информация о вычислительной сложности Python операций, проверить нашу подробную статью о теме.

Это решение не работает на месте и немного сложно читать из-за многих преобразований между структурами данных.

2.4. Удалите случайно распределенные элементы из списка с использованием понимания списка

Лучший способ сделать это в Python на самом деле очень близко к тому, что мы видели в первом разделе этой статьи, в котором мы еемали по поводу списка и удалили элементы, для которых определенное условие было правдой.

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

Python предоставляет именно то, что нам нужно получить желаемый результат в одну линейку кода: список потенциалов.

todo_list = [task for task in todo_list if not task.is_done()]

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

После вышеуказанной линии кода адрес памяти, к которому переменная to_list Точки изменились!

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

Вот код:

[todo_list.remove(task) for task in todo_list if task.is_done()]

Будьте честны, как долго вы взяли, чтобы обернуть голову вокруг этого?

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

Итак, что мы на самом деле делаем, это злоупотреблять в понимании списка для итерации за to_list и удалите предметы от него.

Вывод

В зависимости от распределения предметов в списке есть разные решения.

  1. Если вы хотите удалить все элементы из списка, используйте метод списка Очистить () Отказ
  2. Если вы хотите удалить непрерывный диапазон из списка или если вы хотите удалить элементы с равными расстояниями между, используйте нарезку оператором del l [Start: Stop] Отказ
  3. Если вы хотите удалить случайно распределенные элементы, используйте список списка, которые выбирают только элементы, которые вы хотите сохранить – это решение, которое я рекомендую.

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

Куда пойти отсюда?

Достаточно теории, давайте познакомимся!

Чтобы стать успешным в кодировке, вам нужно выйти туда и решать реальные проблемы для реальных людей. Вот как вы можете легко стать шестифункциональным тренером. И вот как вы польские навыки, которые вам действительно нужны на практике. В конце концов, что такое использование теории обучения, что никто никогда не нуждается?

Практические проекты – это то, как вы обостряете вашу пилу в кодировке!

Вы хотите стать мастером кода, сосредоточившись на практических кодовых проектах, которые фактически зарабатывают вам деньги и решают проблемы для людей?

Затем станьте питоном независимым разработчиком! Это лучший способ приближения к задаче улучшения ваших навыков Python – даже если вы являетесь полным новичком.

Присоединяйтесь к моим бесплатным вебинаре «Как построить свой навык высокого дохода Python» И посмотрите, как я вырос в моем кодировании бизнеса в Интернете и как вы можете тоже – от комфорта вашего собственного дома.

Присоединяйтесь к свободному вебинару сейчас!