Respuestas:
Enfoque funcional:
Python 3.x
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]
o
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]
Python 2.x
>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]
[y for y in x if y != 2]
__ne__
. Comparar dos valores es un proceso mucho más complejo que simplemente llamar __eq__
o __ne__
en uno de ellos. Puede funcionar correctamente aquí porque solo está comparando números, pero en el caso general eso es incorrecto y es un error.
Puedes usar una lista de comprensión:
def remove_values_from_list(the_list, val):
return [value for value in the_list if value != val]
x = [1, 2, 3, 4, 2, 2, 3]
x = remove_values_from_list(x, 2)
print x
# [1, 3, 4, 3]
in
operador como el remove
método escanean la lista completa (hasta encontrar una coincidencia) para que termine escaneando la lista varias veces de esa manera.
Puede usar la asignación de divisiones si la lista original debe modificarse, mientras sigue utilizando una comprensión eficiente de la lista (o expresión del generador).
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]
x = [ v for v in x if x != 2 ]
propuestas, que crean una nueva lista y cambian x para referirse a ella, dejando intacta la lista original.
Repetir la solución de la primera publicación de una manera más abstracta:
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]
x = [1] * 10000 + [2] * 1000
. El cuerpo del bucle se ejecuta 1000 veces y .remove () tiene que omitir 10000 elementos cada vez que se invoca. Eso huele a O (n * n) para mí, pero no es una prueba. Creo que la prueba sería suponer que el número de 2 en la lista es proporcional a su longitud. Ese factor de proporcionalidad luego desaparece en la notación big-O. Sin embargo, el mejor caso de solo un número constante de 2 en la lista no es O (n ^ 2), solo O (2n), que es O (n).
Todas las respuestas anteriores (aparte de Martin Andersson) crean una nueva lista sin los elementos deseados, en lugar de eliminar los elementos de la lista original.
>>> import random, timeit
>>> a = list(range(5)) * 1000
>>> random.shuffle(a)
>>> b = a
>>> print(b is a)
True
>>> b = [x for x in b if x != 0]
>>> print(b is a)
False
>>> b.count(0)
0
>>> a.count(0)
1000
>>> b = a
>>> b = filter(lambda a: a != 2, x)
>>> print(b is a)
False
Esto puede ser importante si tiene otras referencias a la lista dando vueltas.
Para modificar la lista en su lugar, use un método como este
>>> def removeall_inplace(x, l):
... for _ in xrange(l.count(x)):
... l.remove(x)
...
>>> removeall_inplace(0, b)
>>> b is a
True
>>> a.count(0)
0
En cuanto a la velocidad, los resultados en mi computadora portátil son (todos en una lista de 5000 entradas con 1000 entradas eliminadas)
Entonces, el ciclo .remove es aproximadamente 100 veces más lento ....... Hmmm, tal vez se necesita un enfoque diferente. Lo más rápido que he encontrado es usar la comprensión de la lista, pero luego reemplazar el contenido de la lista original.
>>> def removeall_replace(x, l):
.... t = [y for y in l if y != x]
.... del l[:]
.... l.extend(t)
def remove_all(x, l): return [y for y in l if y != x]
entoncesl = remove_all(3,l)
Puedes hacerlo
while 2 in x:
x.remove(2)
A costa de la legibilidad, creo que esta versión es un poco más rápida ya que no obliga a reexaminar la lista, por lo que hacer exactamente el mismo trabajo que eliminar tiene que hacer de todos modos:
x = [1, 2, 3, 4, 2, 2, 3]
def remove_values_from_list(the_list, val):
for i in range(the_list.count(val)):
the_list.remove(val)
remove_values_from_list(x, 2)
print(x)
Enfoque Numpy y tiempos contra una lista / matriz con 1.000.000 elementos:
Tiempos:
In [10]: a.shape
Out[10]: (1000000,)
In [13]: len(lst)
Out[13]: 1000000
In [18]: %timeit a[a != 2]
100 loops, best of 3: 2.94 ms per loop
In [19]: %timeit [x for x in lst if x != 2]
10 loops, best of 3: 79.7 ms per loop
Conclusión: numpy es 27 veces más rápido (en mi cuaderno) en comparación con el enfoque de comprensión de la lista
PD: si quieres convertir tu lista de Python normal lst
en una matriz numpy:
arr = np.array(lst)
Preparar:
import numpy as np
a = np.random.randint(0, 1000, 10**6)
In [10]: a.shape
Out[10]: (1000000,)
In [12]: lst = a.tolist()
In [13]: len(lst)
Out[13]: 1000000
Cheque:
In [14]: a[a != 2].shape
Out[14]: (998949,)
In [15]: len([x for x in lst if x != 2])
Out[15]: 998949
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)
Quizás no sea el más pitónico pero sigue siendo el más fácil para mí jaja
Para eliminar todas las ocurrencias duplicadas y dejar una en la lista:
test = [1, 1, 2, 3]
newlist = list(set(test))
print newlist
[1, 2, 3]
Aquí está la función que he usado para el Proyecto Euler:
def removeOccurrences(e):
return list(set(e))
Creo que esto es probablemente más rápido que cualquier otra forma si no le importa el orden de las listas, si se preocupa por el pedido final, almacene los índices del original y recurra a eso.
category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]
for i in range(a.count(' ')):
a.remove(' ')
Mucho más simple, creo.
Dejar
>>> x = [1, 2, 3, 4, 2, 2, 3]
La solución más simple y eficiente como ya se publicó anteriormente es
>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]
Otra posibilidad que debería usar menos memoria pero ser más lenta es
>>> for i in range(len(x) - 1, -1, -1):
if x[i] == 2:
x.pop(i) # takes time ~ len(x) - i
>>> x
[1, 3, 4, 3]
Resultados de tiempo para listas de longitud 1000 y 100000 con entradas coincidentes del 10%: 0,16 frente a 0,25 ms y 23 frente a 123 ms.
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list():
for list in lists:
if(list!=7):
print(list)
remove_values_from_list()
Resultado: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list(remove):
for list in lists:
if(list!=remove):
print(list)
remove_values_from_list(7)
Resultado: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
hello = ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
#chech every item for a match
for item in range(len(hello)-1):
if hello[item] == ' ':
#if there is a match, rebuild the list with the list before the item + the list after the item
hello = hello[:item] + hello [item + 1:]
print hello
['Hola Mundo']
Acabo de hacer esto para una lista. Solo soy un principiante. Un programador un poco más avanzado seguramente puede escribir una función como esta.
for i in range(len(spam)):
spam.remove('cat')
if 'cat' not in spam:
print('All instances of ' + 'cat ' + 'have been removed')
break
También podemos eliminar todo en el lugar usando del
o pop
:
import random
def remove_values_from_list(lst, target):
if type(lst) != list:
return lst
i = 0
while i < len(lst):
if lst[i] == target:
lst.pop(i) # length decreased by 1 already
else:
i += 1
return lst
remove_values_from_list(None, 2)
remove_values_from_list([], 2)
remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)], 2)
print(len(lst))
Ahora para la eficiencia:
In [21]: %timeit -n1 -r1 x = random.randrange(0,10)
1 loop, best of 1: 43.5 us per loop
In [22]: %timeit -n1 -r1 lst = [random.randrange(0, 10) for x in range(1000000)]
g1 loop, best of 1: 660 ms per loop
In [23]: %timeit -n1 -r1 lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)]
...: , random.randrange(0,10))
1 loop, best of 1: 11.5 s per loop
In [27]: %timeit -n1 -r1 x = random.randrange(0,10); lst = [a for a in [random.randrange(0, 10) for x in
...: range(1000000)] if x != a]
1 loop, best of 1: 710 ms per loop
Como vemos, la versión in situ remove_values_from_list()
no requiere memoria adicional, pero lleva mucho más tiempo ejecutarla:
Nadie ha publicado una respuesta óptima para la complejidad del tiempo y el espacio, así que pensé en intentarlo. Aquí hay una solución que elimina todas las apariciones de un valor específico sin crear una nueva matriz y en un tiempo de complejidad eficiente. El inconveniente es que los elementos no mantienen el orden .
Complejidad de tiempo: O (n)
Complejidad de espacio adicional: O (1)
def main():
test_case([1, 2, 3, 4, 2, 2, 3], 2) # [1, 3, 3, 4]
test_case([3, 3, 3], 3) # []
test_case([1, 1, 1], 3) # [1, 1, 1]
def test_case(test_val, remove_val):
remove_element_in_place(test_val, remove_val)
print(test_val)
def remove_element_in_place(my_list, remove_value):
length_my_list = len(my_list)
swap_idx = length_my_list - 1
for idx in range(length_my_list - 1, -1, -1):
if my_list[idx] == remove_value:
my_list[idx], my_list[swap_idx] = my_list[swap_idx], my_list[idx]
swap_idx -= 1
for pop_idx in range(length_my_list - swap_idx - 1):
my_list.pop() # O(1) operation
if __name__ == '__main__':
main()
Sobre la velocidad!
import time
s_time = time.time()
print 'start'
a = range(100000000)
del a[:]
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 3.25
s_time = time.time()
print 'start'
a = range(100000000)
a = []
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 2.11
Qué hay de malo en:
Motor=['1','2','2']
For i in Motor:
If i != '2':
Print(i)
Print(motor)
Usando anaconda