2014-01-30 3 views
0

Если у меня есть немного Python, как:Как удалить все совпадения в списке Python?

n = [1, 3, 5, 1] 
n.remove(1) 
print n 

п вернется [3, 5, 1], потому что .remove() Завершает после того, как находит свой первый матч. Что я мог сделать, чтобы вернуть только [3, 5], найдя все совпадений (или в этом случае все 1 s)?

ответ

9

При создании нового списка в порядке:

n = [x for x in n if x != 1] 

Конечно, вы можете также использовать назначение ломтика, чтобы изменить список на месте:

n[:] = [x for x in n if x != 1] 
+0

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

+0

Да, временная копия сделана для назначения среза. Когда я говорю «на месте», я имею в виду, что 'n' все еще ссылается на тот же список (с измененным содержимым), а не на' n', привязанный к совершенно другому списку. Это действительно имеет значение, если есть другие ссылки на список. –

2

функция использование фильтра

n = [1, 3, 5, 1] 
filter(lambda a:a is not 1,n) 
[3,5] 

Редакция

n = [1, 3, 5, 1] 
filter(lambda a:a != 1,n) 
[3,5] 
+5

'is not' tests (non) identity, not (in) равенство. Вместо этого вы хотите «a! = 1» - он работает только на '1' от fluke, в основном (см. [Здесь] (http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly- с целыми числами), например.) – DSM

+0

исправлено, не знало об идентичности переменных, будет заботиться, спасибо – markcial

0

Это не так, как я обычно делаю это, но:

n = [1, 3, 5, 1] 
REMOVECHAR = 1 
while REMOVECHAR in n: 
    n.remove(REMOVECHAR) 
# could also do: 
# while 1: 
#  try: n.remove(REMOVECHAR) 
#  except ValueError as e: break 

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

n = [1,3,5,1] 
REMOVECHAR = 1 
nn = [element for element in n if element != REMOVECHAR] 
+0

Зачем вы капитализировали 'REMOVECHAR'? – rlms

+0

Потому что я использую его как константу, которая написана в UPPERCASE в соответствии с [PEP8] (http://www.python.org/dev/peps/pep-0008/#constants), хотя я полагаю, что технически я должен был бы используется 'REMOVE_CHAR': P –

+0

' try \ except' версия лучше, так как вам не нужно проверять членство O (n) на каждой итерации.Хотя все же, неэффективен, так как вы по-прежнему просматриваете каждый элемент, который предшествует совпадению, даже если вы уже проверили его, пока все экземпляры не будут удалены. –

0

Простой List Comprehension -

>>> n = [1, 3, 5, 1] 
>>> n = [e for e in n if e != 1] 
>>> n 
[3, 5] 

Если вы хотите, чтобы удалить более одного элемента -

>>> g = [1,3] 
>>> n = [e for e in n if e not in g] 
>>> n 
[5] 
0

Вы можете перебирать в обратном направлении по списку и поп-элементов, которые соответствуют.

def remove_all_in_place(target, sequence): 
    cursor = len(target) - 1 
    while cursor >= 0: 
     if sequence[cursor] == target: 
      sequence.pop(cursor) 
     cursor -= 1 

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

+0

Я всегда следовал правилу «Не работайте с списком, итерации на нем «. Ваша 'lst.pop (игла)' фактически работает безопасно, итерации через 'lst'? –

+1

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

Смежные вопросы