Удалить все повторения элемента в списке без использования циклов (Python) - PullRequest
0 голосов
/ 20 сентября 2018

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

foo_list = [1,2,3,4,2,3]

И давайте предположим, что я пытаюсь избавиться от предмета 2.Если я использую метод .remove, он просто удалит первый 2 в моем списке.

foo_list.remove(2)

Будет иметь в качестве вывода [1,3,4,2,3], но я хотел бы иметь в качестве вывода [1,3,4,3].Конечно, я могу сделать это, используя список понимания, такой как:

[item for item in foo_list if item !=2]

Я мог бы также сделать set (foo_list), но я хочу сохранить элементы репликации, которые не являются выбранными, 2 вэтот случай.

Но я пытаюсь найти способ сделать это без необходимости цикла for, поскольку мой реальный список содержит более 100000 элементов, что делает эту процедуру очень медленной.Есть ли какой-либо метод, аналогичный remove, который позволил бы мне удалить все выбранные элементы?

Любая помощь будет принята.

Ответы [ 5 ]

0 голосов
/ 20 сентября 2018

Редактировать: (оптимизировать производительность понимания списка)

Для оптимизации понимания списка в этом примере, учитывая, что список «поиск» со словами, которые будут удалены, являются уникальнымидо этого он может быть преобразован в set для улучшения производительности поиска во время понимания списка.

def remove_all_from_other_list(_list, _remove_list):
    _remove_list = set(_remove_list)
    return [v for v in _list if v not in _remove_list]

Проверьте эту суть: https://gist.github.com/fsschmitt/4b2c8963485e46b4483746624b5a2bff

Чтобы проверить различия в производительности между всемирешения, представленные здесь.

Резюме:

  • понимание списка : 55,785589082 секунд.

  • понимание списка с набором : 17,348955028000006 секунд.

  • фильтрация списка : 79,495240288 секунд.

  • для циклов : 70,14259565200001 секунд.


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

def remove_all(_list, value):
    return [v for v in _list if v != value]

Хотя вы всегда можете воспользоваться преимуществами метода фильтрации:

def remove_all(_list, value):
    return list(filter(lambda v: v != value, _list))

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

>>> remove_all([1, 2, 3, 4, 2, 3], 2)
[1, 3, 4, 3]

Это определенно будет более эффективным, чем вызов 'Метод .remove 'несколько раз и проверка, все ли еще встречаются случаи.

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

0 голосов
/ 20 сентября 2018

remove () может удалить только 1-е вхождение элемента.У меня мало идей о времени, но вы можете попробовать это:

foo_list = [1,2,3,4,2,3]
while 2 in foo_list: foo_list.remove(2)
print(foo_list)
0 голосов
/ 20 сентября 2018

Вы можете использовать фильтр с лямбда-подобным фильтром (lambda x: x! = 2, foo_list)

0 голосов
/ 20 сентября 2018

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

Вы можете попробовать это:

def remove_repeated_elements(element, list_):
    try:
        while True:
            list_.remove(list_.index(element))
    except ValueError:
        pass
0 голосов
/ 20 сентября 2018

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

list(filter(lambda x: x != 2, foo_list))

Давайте рассмотрим некоторые моменты времени с использованием IPython

import random

# make a large list of ints
bar_list = [random.randint(1,10000) for _ in range(100000)]

%timeit list(filter(lambda x: x != 2, bar_list))
100 loops, best of 3: 10.3 ms per loop

%timeit [x for x in bar_list if x != 2]
100 loops, best of 3: 4.34 ms per loop

Понимание списка примерно в два раза быстрее по сравнению с использованием фильтра

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...