¿Hay una manera simple de eliminar un elemento de lista por valor?


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

del a[b]
print(a)

Lo anterior muestra el siguiente error:

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

Entonces tengo que hacer esto:

a = [1, 2, 3, 4]

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

print(a)

¿Pero no hay una manera más simple de hacer esto?


14
Calcula el índice de 6 en su lista. Pero 6 no está en tu lista ... ¿qué se supone que sucederá? :)
Johannes Charra

55
esto no tiene nada que ver con eliminar un valor en una lista, ya que su código no alcanza la instrucción del. Tal vez deberías retitúlelo "cómo consigo el índice de un valor que no está en una lista Respuesta obvia -. No se puede.
David Kirby

57
@ Dave Bueno, en realidad no. Quiere eliminar un elemento de la lista, independientemente de si existe o no, para no obtener el índice de un elemento inexistente. La pregunta está bien hecha.
ibz

Además del punto, pero un desnudo exceptes una mala práctica . Usar except Exceptioncomo mínimo.
wjandrea

Respuestas:


1565

Para eliminar la primera aparición de un elemento en una lista, simplemente use list.remove:

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

Tenga en cuenta que no elimina todas las ocurrencias de su elemento. Use una lista de comprensión para eso.

>>> 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]

144
Falla si el elemento no está en la lista. :)
ibz

21
La comprensión de la lista @ibz no falla incluso si el elemento no está en la lista, ¿verdad?
IsaacS

76
Para aclarar para cualquier persona que descreme, "falla" en el sentido de que genera una excepción ValueError.
Casey Falk

10
La comprensión de la lista cambia la referencia de la lista, por lo que si hay una copia de la referencia en alguna parte, la eliminación no seguirá.
Sebastien

¿Cuál es la complejidad de si removees O (n)?
Rasmi Ranjan Nayak

184

Por lo general, Python lanzará una excepción si le dice que haga algo que no puede, por lo que deberá hacer lo siguiente:

if c in a:
    a.remove(c)

o:

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

Una excepción no es necesariamente algo malo siempre y cuando sea una que esté esperando y maneje adecuadamente.


99
Es mejor prevenir que curar. Si primero puede verificar condiciones excepcionales (ejemplo a), debería hacerlo.
Gusdor

82
Si bien esto es cierto en otros idiomas, en Python es "más fácil pedir perdón que permiso". docs.python.org/2/glossary.html#term-eafp
Dave Webb

66
@Gusdor: si la lista se comparte entre subprocesos, entonces a.remove(c)podría fallar a pesar de la if c in averificación ( apodría modificarse en otro subproceso después de la c in averificación pero antes de la a.remove(c)llamada). try/excepto se podrían usar cerraduras para evitar la condición de carrera.
jfs

77
@JFSebastian si una lista se comparte entre hilos y no está aplicando secciones críticas, entonces tiene problemas más grandes.
Gusdor

44
@Gusdor, el idioma de Pythonique es intentar sin verificar y detectar la excepción si ocurre. Es más eficiente (solo una búsqueda en lugar de dos), aunque un poco más feo
Jeet

80

Tu puedes hacer

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

pero arriba necesita buscar 6 en la lista 2 veces, así que intente, excepto sería más rápido

try:
    a.remove(6)
except:
    pass

55

Considerar:

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

Para eliminar todas las ocurrencias, puede usar la función de filtro en python. Por ejemplo, se vería así:

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

Por lo tanto, mantendría todos los elementos de a != 2.

Para sacar uno de los elementos, use

a.remove(2)

¿Por qué te envuelves filter()en otro list()? Según el manual, ya devuelve una lista.
Olaf Dietsche

8
@OlafDietsche En Python 3.x, devuelve un objeto de filtro (en 2.x, devuelve una lista), por lo que tengo que convertir "a" en una lista para que tenga alguna funcionalidad.
mathwizurd

17

Aquí se explica cómo hacerlo en el lugar (sin comprensión de la lista):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

Muy inteligente, realmente me gusta, desafortunadamente parece ser tan ineficiente como la respuesta más popular. La solución de Gil es en realidad mucho más rápida para listas gigantes con solo unas pocas ocurrencias del valor que desea eliminar.
Larold

1
@Larold La forma más rápida sería una pregunta separada. Mi dinero está en la lista de comprensión en el caso general. Esta solución debería funcionar realmente bien si el valor es frecuente en la lista de entrada y no se utiliza la comprensión de la lista. Pruebe Pypy, datos numpy en Cython. [La respuesta de @ Gill es O(n*n)innecesaria (compárese 1e6 y 1e12; no quiere arriesgarse a esto último). while 1: L.remove(value)y volver a ValueErrorfuncionar podría funcionar bien con unas pocas valuelistas pequeñas en CPython.
jfs

13

Si sabe qué valor eliminar, aquí hay una manera simple (tan simple como se me ocurre, de todos modos):

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

Usted obtendrá [0, 0, 2, 3, 4]


44
¿Por qué no usar while 1 in a:como estructura de bucle?
TerminalDilettante

12
Aquí es O(n^2)donde estaría una comprensión O(n).
Físico loco

1
Por supuesto, @MadPhysicist tiene razón, y la versión de TerminalDilettante es mucho más pitónica, incluso si no nos importa el rendimiento. En 2013 comencé a aprender Python y hoy en día me avergüenzo de lo que escribí en ese momento.
Gil

11

Otra posibilidad es usar un conjunto en lugar de una lista, si un conjunto es aplicable en su aplicación.

IE si sus datos no están ordenados y no tienen duplicados, entonces

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

Está libre de errores.

A menudo, una lista es solo un contenedor útil para artículos que en realidad no están ordenados. Hay preguntas sobre cómo eliminar todas las ocurrencias de un elemento de una lista. Si no quieres engañar en primer lugar, una vez más, un conjunto es útil.

my_set.add(3)

no cambia my_set desde arriba.


10

Como se indica en muchas otras respuestas, list.remove()funcionará, pero arroje un ValueErrorsi el elemento no estaba en la lista. Con Python 3.4+, hay un enfoque interesante para manejar esto, usando el Suppress contextmanager :

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

8

Encontrar un valor en una lista y luego eliminar ese índice (si existe) es más fácil usando el método remove de la 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]

Si hace esto a menudo, puede resumirlo en una función:

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

8

Este ejemplo es rápido y eliminará todas las instancias de un valor de la lista:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

2
si haces esto, solo deberías seguir breakadelante except ValueError.
Anthon

8

En una linea:

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

a veces es útil.

Aún más fácil:

if 'b' in a: a.remove('b')

7

Si sus elementos son distintos, entonces bastará una simple diferencia de conjunto.

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]

2
Si sus elementos son distintos y no le importa el orden .
Tom Zych

2

También 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]
>>> 

2

Sobrescriba la lista indexando todo excepto los elementos que desea eliminar

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

2

Con un bucle for y una condición:

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

Y si desea eliminar algunos, pero no 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

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)

Es sin usar la función de filtro
Ravikiran D

1

Digamos, por ejemplo, que queremos eliminar todos los 1 de x. Así es como lo haría:

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

Ahora, este es un uso práctico de mi método:

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

Y este es mi método en una sola línea:

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

Ambos producen esto como una salida:

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

Espero que esto ayude. PD, tenga en cuenta que esto se escribió en la versión 3.6.2, por lo que es posible que deba ajustarlo para versiones anteriores.


1

Tal vez sus soluciones funcionen con ints, pero no me funcionan con dictionarys.

Por un lado, remove () no me ha funcionado. Pero tal vez funciona con tipos básicos. Supongo que el siguiente código también es la forma de eliminar elementos de la lista de objetos.

Por otro lado, 'del' tampoco ha funcionado correctamente. En mi caso, usando python 3.6: cuando trato de eliminar un elemento de una lista en un bucle 'for' con el comando 'del', python cambia el índice en el proceso y bucle se detiene prematuramente antes de tiempo. Solo funciona si elimina elemento por elemento en orden inverso . De esta manera, no cambia el índice de matriz de elementos pendientes cuando lo está revisando

Entonces, estoy acostumbrado:

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

donde 'lista' es como [{'clave1': valor1 '}, {' clave2 ': valor2}, {' clave3 ': valor3}, ...]

También puedes hacer más pitónico usando enumerate:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

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]

0

Esto elimina todas las instancias de "-v"la matriz sys.argvy no se queja si no se encontraron instancias:

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

Puede ver el código en acción, en un archivo llamado 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']

-1

esta es mi respuesta, solo use while y for

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()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.