Busco una forma de eliminar todos los valores dentro de una lista de otra lista.Eliminar todos los valores dentro de una lista de otra lista?
Algo como esto:
a = range(1,10)
a.remove([2,3,7])
print a
a = [1,4,5,6,8,9]
Busco una forma de eliminar todos los valores dentro de una lista de otra lista.Eliminar todos los valores dentro de una lista de otra lista?
Algo como esto:
a = range(1,10)
a.remove([2,3,7])
print a
a = [1,4,5,6,8,9]
>>> a = range(1, 10)
>>> [x for x in a if x not in [2, 3, 7]]
[1, 4, 5, 6, 8, 9]
a = range(1,10)
itemsToRemove = set([2, 3, 7])
b = filter(lambda x: x not in itemsToRemove, a)
o
b = [x for x in a if x not in itemsToRemove]
No cree el conjunto dentro de la lambda
o dentro de la comprensión. Si lo haces, será recreado en cada iteración, derrotando el punto de usar un conjunto.
Otros han sugerido formas de hacer una nueva lista después de filtrar, p.
newl = [x for x in l if x not in [2,3,7]]
o
newl = filter(lambda x: x not in [2,3,7], l)
pero a partir de su pregunta que parece que quiere en lugar de modificación para que pueda hacer esto, esto también será mucho más rápido si la lista original es largo y artículos que ser eliminado menos
l = range(1,10)
for o in set([2,3,7,11]):
try:
l.remove(o)
except ValueError:
pass
print l
salida: [1, 4, 5, 6, 8, 9]
estoy comprobando para ValueError excepción por lo que funciona incluso si los artículos no están en la lista original.
Además, si no necesita solución de modificación in situ por S.Mark
es más simple.
si realmente necesita una modificación in situ, las respuestas anteriores se pueden modificar a: 'a [:] = [x para x en a si x no en [2,3,7]]'. Esto será más rápido que tu código. –
sí a [:] se puede usar, pero no es obvio que sea más rápido, para listas largas con pocos valores para eliminar mi código será mucho más rápido, p. try list para eliminar = [1] :) –
@Anurag: Parece que tienes razón; las pruebas de tiempo hacen que parezca que quitarlas en su lugar es más rápido. –
La forma más sencilla es
>>> a = range(1, 10)
>>> for x in [2, 3, 7]:
... a.remove(x)
...
>>> a
[1, 4, 5, 6, 8, 9]
Un posible problema aquí es que cada vez que se llama a eliminar(), todos los artículos son barajadas por la lista para llenar el agujero. Entonces, si a
crece muy grande, esto terminará siendo bastante lento.
De esta manera se crea una nueva lista. La ventaja es que se evita todo el mezclarse del primer enfoque
>>> removeset = set([2, 3, 7])
>>> a = [x for x in a if x not in removeset]
Si desea modificar a
en su lugar, sólo se requiere un pequeño cambio
>>> removeset = set([2, 3, 7])
>>> a[:] = [x for x in a if x not in removeset]
@gnibbler, su afirmación * "Así que si' a' crece muy grande, esto terminará siendo bastante lento. "* Es un poco engañoso. Si solo la longitud de 'a' no está limitada, todos los fragmentos que proporcionó son O (n). El problema ** real ** con 'eliminar' es que solo elimina * la primera aparición * de sus argumentos, no todas las ocurrencias. También es más acorde con escribir un código claro e idiomático para hacer una nueva lista en lugar de mutar la anterior. –
@Mike, intenté mantener la respuesta simple ya que el OP ha usado la etiqueta de principiante. –
"simple" no es excusa para * incorrecto *. –
>>> a=range(1,10)
>>> for i in [2,3,7]: a.remove(i)
...
>>> a
[1, 4, 5, 6, 8, 9]
>>> a=range(1,10)
>>> b=map(a.remove,[2,3,7])
>>> a
[1, 4, 5, 6, 8, 9]
No use 'map' para los efectos secundarios. 'map' es para recoger el resultado de un grupo de llamadas. Para los bucles son la herramienta para hacer algo un montón de veces. –
si lo que quiere decir con efectos secundarios son esos "ninguno" devueltos por 'mapa', entonces puede" enmascararse ". Aparte de eso, sigue siendo válido, y me gusta la concisión de la misma. – ghostdog74
Si no lo hace tiene valores repetidos, puede usar establecer la diferencia.
x = set(range(10))
y = x - set([2, 3, 7])
# y = set([0, 1, 4, 5, 6, 8, 9])
y luego volver a la lista, si es necesario.
Tenga en cuenta que esto mezclará la lista resultante. –
El orden de la lista puede cambiar, pero de forma determinista. No está "barajado" en el sentido aleatorio. – dansalmo
también, si su lista original x tiene duplicados, después de la operación set(), solo se guarda uno. –
Estaba buscando una forma rápida de hacer el tema, así que hice algunos experimentos con las formas sugeridas. Y me sorprendieron los resultados, así que quiero compartirlo contigo.
Los experimentos se realizaron utilizando pythonbenchmark herramienta y con
a = range(1,50000) # Source list
b = range(1,15000) # Items to remove
Resultados:
def comprehension(a, b):
return [x for x in a if x not in b]
5 intentos, tiempo medio de 12,8 seg
def filter_function(a, b):
return filter(lambda x: x not in b, a)
5 intentos, tiempo medio de 12,6 seg
def modification(a,b):
for x in b:
try:
a.remove(x)
except ValueError:
pass
return a
5 intentos, el tiempo promedio 0,27 seg
def set_approach(a,b):
return list(set(a)-set(b))
5 intentos, tiempo medio 0,0057 sec
También hice otra medición con el tamaño de las entradas más grandes para las dos últimas funciones
a = range(1,500000)
b = range(1,100000)
Y los resultados:
Para la modificación (quitar método) - tiempo promedio es de 252 segundos para la aproximación conjunto - tiempo promedio es de 0,75 segundo
Así se puede ver que el enfoque con conjuntos es significativamente más rápido que otros. Sí, no mantiene artículos similares, pero si no lo necesita, es para usted. Y casi no hay diferencia entre la comprensión de la lista y el uso de la función de filtro. Usar 'eliminar' es ~ 50 veces más rápido, pero modifica la lista de fuentes. Y la mejor opción es usar conjuntos: ¡es más de 1000 veces más rápido que la comprensión de listas!
muy interesante. No hubiera usado set, intuitivamente la conversión debería agregar sobrecarga. aparentemente mi intuición estaba equivocada. gracias por la idea – lhk
¿Qué pasa si tengo una lista '[1,2,2,2,3,4]' y una sublista '[2,3]', entonces el resultado debería ser '[1,2,2,4 ] ', ¿hay alguna manera Pythonic de hacer eso? – user
@user esto te lleva la mayor parte del camino, pero tu problema es diferente. l = [1,2,2,3,4] sl = [2,3] [x para x en [l [n: n + 2] para n en rango (0, len (l)) [ :: 2]] si x! = Sl] – jsh