Existe uma maneira simples de excluir um elemento da lista por valor?

942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

O acima mostra o seguinte erro:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
ValueError: list.index(x): x not in list

Então eu tenho que fazer isso:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

Mas não há uma maneira mais simples de fazer isso?

zjm1126
fonte
14
Você calcula o índice de 6 na sua lista. Mas 6 não está na sua lista ... então o que deveria acontecer? :)
Johannes Charra
5
isso não tem nada a ver com a exclusão de um valor em uma lista, pois seu código não atinge a instrução del. Talvez você deve mude o título "como faço para obter o índice de um valor que não está em uma lista de respostas Óbvio -. Você não pode.
Dave Kirby
57
@ Dave Bem, na verdade não. Ele deseja excluir um item da lista, independentemente de ele existir ou não, para não obter o índice de um item inexistente. A pergunta é bem feita.
ibz 15/08/11
Além do ponto, mas um nu excepté uma prática ruim . Use except Exceptionno mínimo.
wjandrea 22/03

Respostas:

1564

Para remover a primeira ocorrência de um elemento em uma lista, basta usar list.remove:

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

Lembre-se de que ele não remove todas as ocorrências do seu elemento. Use uma lista de compreensão para isso.

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]
Johannes Charra
fonte
144
Falha se o elemento não estiver na lista. :)
ibz 15/08
21
A compreensão da lista @ibz não falha, mesmo que o elemento não esteja na lista, falha?
Isaacs
76
Para esclarecer qualquer pessoa que esteja pesquisando, "falha" no sentido em que gera uma exceção ValueError.
Casey Falk
10
A compreensão da lista altera a referência da lista, portanto, se houver uma cópia da referência em algum lugar, a remoção não será seguida.
Sebastien
Qual é a complexidade de removeO (n)?
Rasmi Ranjan Nayak
184

Normalmente, o Python lança uma exceção se você pedir para fazer algo que não pode, então você terá que fazer:

if c in a:
    a.remove(c)

ou:

try:
    a.remove(c)
except ValueError:
    pass

Uma exceção não é necessariamente uma coisa ruim, desde que você esteja esperando e lidando adequadamente.

Dave Webb
fonte
9
Prevenção é melhor que a cura. Se você pode verificar primeiro condições excepcionais (exemplo a), deve.
Gusdor
82
Embora isso seja verdade em outras línguas, no Python é "mais fácil pedir perdão do que permissão". docs.python.org/2/glossary.html#term-eafp
Dave Webb
6
@ Gusdor: se a lista for compartilhada entre threads, a.remove(c)pode falhar mesmo assim, apesar da if c in averificação ( apode ser modificada em outro segmento após a c in averificação, mas antes da a.remove(c)chamada). try/exceptou bloqueios podem ser usados ​​para evitar a condição de corrida.
jfs
7
@JFSebastian se uma lista for compartilhada entre threads e você não estiver aplicando seções críticas, terá problemas maiores.
Gusdor
4
@Gusdor, o idioma Pythonique é tentar sem verificar e capturar a exceção, se ocorrer. É mais eficiente (apenas uma pesquisa em vez de dois), embora um pouco mais feio
Jeet
80

Você pode fazer

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

mas acima precisa procurar 6 na lista a 2 vezes, então tente exceto seria mais rápido

try:
    a.remove(6)
except:
    pass
VOCÊ
fonte
55

Considerar:

a = [1,2,2,3,4,5]

Para remover todas as ocorrências, você pode usar a função de filtro em python. Por exemplo, seria semelhante a:

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

Então, manteria todos os elementos de a != 2.

Para retirar apenas um dos itens, use

a.remove(2)
mathwizurd
fonte
Por que você envolve filter()outro list()? De acordo com o manual, ele já retorna uma lista.
Olaf Dietsche
8
@OlafDietsche No Python 3.x, ele retorna um objeto de filtro (no 2.x, ele retorna uma lista), então eu tenho que converter "a" em uma lista para que ela tenha alguma funcionalidade.
mathwizurd
17

Veja como fazê-lo no local (sem compreensão da lista):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]
jfs
fonte
Muito inteligente - eu realmente gosto disso - infelizmente parece ser tão ineficiente quanto a resposta mais popular. A solução da Gil é realmente muito mais rápida para listas gigantes, com apenas algumas ocorrências do valor que você deseja remover.
Larold 22/08/14
1
@ Larar A maneira mais rápida seria uma pergunta separada. Meu dinheiro está na compreensão da lista no caso geral. Esta solução deve ter um desempenho muito bom se o valor for frequente na lista de entrada e a compreensão da lista não for usada. Experimente o Pypy, dados numpy no Cython. [@ A resposta de Gill é O(n*n)desnecessária (compare 1e6 e 1e12 - você não quer arriscar o último). while 1: L.remove(value)e o retorno ValueErrorpode funcionar bem com algumas valueou pequenas listas no CPython.
jfs
13

Se você souber qual valor excluir, eis uma maneira simples (de qualquer maneira, o mais simples que eu puder imaginar):

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

Você terá [0, 0, 2, 3, 4]

gil
fonte
4
Por que não usar while 1 in a:como estrutura de loop?
TerminalDilettante
12
É aqui O(n^2)que estaria uma compreensão O(n).
Mad Physicist
1
É claro que o @MadPhysicist está certo, e a versão do TerminalDilettante é muito mais pitônica, mesmo que não nos importemos com o desempenho. Em 2013, comecei a aprender Python e hoje em dia muitas vezes tenho vergonha do que escrevi na época.
Gil
11

Outra possibilidade é usar um conjunto em vez de uma lista, se um conjunto for aplicável ao seu aplicativo.

IE, se seus dados não forem solicitados e não tiverem duplicatas,

my_set=set([3,4,2])
my_set.discard(1)

está livre de erros.

Frequentemente, uma lista é apenas um contêiner útil para itens que não são realmente ordenados. Há perguntas perguntando como remover todas as ocorrências de um elemento de uma lista. Se você não quer bobagens em primeiro lugar, mais uma vez um conjunto é útil.

my_set.add(3)

não altera my_set de cima.

GreenAsJade
fonte
10

Como afirmado por várias outras respostas, list.remove()funcionará, mas lance um ValueErrorse o item não estiver na lista. Com o python 3.4+, há uma abordagem interessante para lidar com isso, usando o gerenciador de contexto suprimir :

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')
Felk
fonte
8

Encontrar um valor em uma lista e excluir esse índice (se existir) é mais fácil usando o método de remoção da lista:

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

Se você fizer isso com frequência, poderá agrupá-lo em uma função:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

fonte
8

Este exemplo é rápido e excluirá todas as instâncias de um valor da lista:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]
Chase Adams
fonte
2
Se você fizer isso você deve realmente somente breakno except ValueError.
Anthon
8

Em uma linha:

a.remove('b') if 'b' in a else None

às vezes é útil.

Ainda mais fácil:

if 'b' in a: a.remove('b')
Andrey Suglobov
fonte
7

Se seus elementos forem distintos, uma simples diferença de conjunto será suficiente.

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]
Pagol
fonte
2
Se seus elementos são distintos e você não se importa com a ordem .
precisa saber é o seguinte
2

Também podemos usar .pop:

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 
Super Nova
fonte
2

Sobrescreva a lista indexando tudo, exceto os elementos que você deseja remover

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]
quilojoules
fonte
2

Com um loop for e uma condição:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

E se você deseja remover alguns, mas não todos:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp
user7970984
fonte
1
 list1=[1,2,3,3,4,5,6,1,3,4,5]
 n=int(input('enter  number'))
 while n in list1:
    list1.remove(n)
 print(list1)
Ravikiran D
fonte
É sem usar função de filtro
Ravikiran D
1

Digamos, por exemplo, queremos remover todos os 1s de x. É assim que eu diria:

x = [1, 2, 3, 1, 2, 3]

Agora, este é um uso prático do meu método:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

E este é o meu método em uma única linha:

[x.remove(1) for Item in range(x.count(1))]
print(x)

Ambos produzem isso como uma saída:

[2, 3, 2, 3, 2, 3]

Espero que isto ajude. PS, observe que isso foi escrito na versão 3.6.2, portanto, você pode precisar ajustá-lo para versões mais antigas.

Krohnus Melavea
fonte
1

Talvez suas soluções funcionem com ints, mas não funciona para mim com dicionários.

Por um lado, remove () não funcionou para mim. Mas talvez funcione com tipos básicos. Eu acho que o código abaixo também é a maneira de remover itens da lista de objetos.

Por outro lado, 'del' também não funcionou corretamente. No meu caso, usando python 3.6: quando tento excluir um elemento de uma lista em um comando 'for' bucle com 'del', o python altera o índice no processo e o bucle para prematuramente antes do tempo. Só funciona se você excluir elemento por elemento em ordem inversa . Dessa forma, você não altera o índice da matriz de elementos pendentes quando está passando por ele

Então, eu sou usado:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

onde 'list' é como [{'key1': value1 '}, {' key2 ': value2}, {' key3 ': value3}, ...]

Além disso, você pode fazer mais python usando enumerar:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)
David Martínez
fonte
0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]
Brijesh Kushwaha
fonte
0

Isso remove todas as instâncias da "-v"matriz sys.argve não reclama se nenhuma instância foi encontrada:

while "-v" in sys.argv:
    sys.argv.remove('-v')

Você pode ver o código em ação, em um arquivo chamado speechToText.py:

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']
Mike Slinn
fonte
-1

esta é a minha resposta, basta usar enquanto e para

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
guoxy2016
fonte